月次データで「年/月」と言う形式(e.g. 2013/11、2014/2)は良く見かけると思いますが、Rのread.table関数でデータフレームに読み込むと文字列型*1になってしまいます。日付型でないと、subset関数などで絞り込むときに不便ですね*2。しかし、as.Date関数はこの形式を日付型に変えてくれません。そこで、ちょっとした細工をしてみましょう。
日経平均.txtと言うファイルを読み込みます。
df1 <- read.table("日経平均.txt", header=TRUE, sep="\t")
中身は、こんな感じです。
年月 | 始値 | 高値 | 安値 | 終値 |
---|---|---|---|---|
1994/01 | 17369.74 | 20229.12 | 17369.74 | 20229.12 |
1994/02 | 20416.34 | 20416.34 | 18931.39 | 19997.20 |
1994/03 | 20216.62 | 20677.77 | 19111.92 | 19111.92 |
as.Dateをすると、こんな悲劇に。日付がないのがいけない模様です。
as.Date(df1$年月,"%Y/%m")
[1] NA NA NA NA NA NA NA NA NA
gsubで置換して日付を足せば変換できます。
df1$年月日 <- as.Date(gsub("([0-9]+)/([0-9]+)", "\\1/\\2/1", df1$年月))
これをsubset(df1, 年月日>="2013-1-1" & 年月日<="2013-12-31")のように絞り込めます。
日付を月末にする
少し応用して、2013-12-31のように月末値を代入しましょう。月末日は毎月かわりますし、うるう年の処理もいることに注意してください。
まずは月始日*3で、Date型ではなく、POSIXlt型の変数を作ります。
tmpDate <- as.POSIXlt(gsub("([0-9]+)/([0-9]+)", "\\1/\\2/1", df1$年月))
tmpDate$yearで年から1900を引いたものが、tmpDate$monで月から1を引いたものが、tmpDate$mdayで日が取得できます。これから翌月の月始日の日付を作成します。12月の翌月は、年が一つ増えて、1月に戻ることに注意してください。
nextMonth <- ISOdate(tmpDate$year+1900+(tmpDate$mon+1==12)*1, ((tmpDate$mon+1) %% 12)+1, 1)
他の環境に習熟している人は、mktimeではなくISOdateかと思うかも知れません。
翌月の月始日の24時間前(=3600*24秒)が当月の月末です。
df1$年月日 <- as.Date(nextMonth - 3600*24)
別解
見直して、コードの見通しを改善しました。
tmpDate <- as.POSIXlt(gsub("([0-9]+)/([0-9]+)", "\\1/\\2/1", df1$年月)) tmpDate$mon <- tmpDate$mon + 1 # 1ヶ月ずらす(桁上がり処理はされる) tmpDate$mday <- 0 # 翌月の0日目は、当月の月末 df1$年月日 <- as.Date(tmpDate)