xtsへのコンバート

※xtsの使い方自体はxtsライブラリを使ってみるー1xtsライブラリを使ってみるー2参照のこと

csvファイルに金融時系列データを保存する場合、「1列目:日時、2列目以降:資産価格」のようなフォーマットが多い(Excel脳)
このようなデータをRで扱う場合、read.csvで読み込むとdata.frame型になる。
これを処理が大変便利なxts型に変換したいので関数を書く・・・までもなく

#hogeにdata.frame型のデータが入る
as.xts(read.zoo(hoge))

でイケた。具体的なデータを使ってやってみると

#テスト用データをdropboxにおいてあるのでそれを使う
#ここで使用している為替レートのようなものは実際の値ではありません。あくまでサンプルデータです。
file.currency.rate <- "http://dl.dropbox.com/u/9923352/CURRENCYRATE.csv" 
currency.rate <-  as.xts(read.zoo(read.csv(file.currency.rate)))
#currency.rate <-  as.xts(read.zoo(file.currency.rate,header=TRUE,sep=","))
#と書いても同じ動作になった(2011/2/2追記)

実行後、型と値をチェックするとちゃんとなっているのがわかる。

> class(currency.rate)
[1] "xts" "zoo"
> currency.rate
           USDJPY EURJPY AUDJPY
2010-07-28  85.17 115.83  75.43
2010-07-29  88.06 113.62  77.70
2010-07-30  84.63 112.44  80.37
2010-08-02  85.99 116.35  77.67
2010-08-03  86.41 110.96  78.06
2010-08-04  84.84 113.34  76.80
2010-08-05  84.56 113.97  77.19
2010-08-06  86.24 115.62  77.16
2010-08-09  85.42 114.04  78.51
2010-08-10  87.68 111.68  75.87

ここに書いたやり方に気がつく前には自作関数を使っていました。
気がつくきっかけをくれた@manozo(twitter)さんに感謝!

〜2012/12/20追記
コメント欄で質問いただいたように最近のパッケージだと上記のコードでは日付が1日前のものになってしまう。

> library(xts)
> file.currency.rate <- "http://dl.dropbox.com/u/9923352/CURRENCYRATE.csv"
> currency.rate <-  as.xts(read.zoo(read.csv(file.currency.rate)))
> currency.rate
           USDJPY EURJPY AUDJPY
2010-07-27  85.17 115.83  75.43
2010-07-28  88.06 113.62  77.70
2010-07-29  84.63 112.44  80.37
2010-08-01  85.99 116.35  77.67
2010-08-02  86.41 110.96  78.06
2010-08-03  84.84 113.34  76.80
2010-08-04  84.56 113.97  77.19
2010-08-05  86.24 115.62  77.16
2010-08-08  85.42 114.04  78.51
2010-08-09  87.68 111.68  75.87

これはxts関数内部での日付変換が日本のタイムゾーンとの相性が悪い事(正しく変換されない)事に起因しているっぽくて、
対策としては以下のようにするのが良い(ような気がしている。もっといい方法知っている方!プリーズ!)
まずは結構無理やりなやり方で

  • 日付を強制的に+1してやる
  • Date型オブジェクトじゃなくてPOSIXct型にしてごまかす
> x <- read.zoo(read.csv(file.currency.rate))
> as.xts(x,order.by=index(x)+1)
           USDJPY EURJPY AUDJPY
2010-07-28  85.17 115.83  75.43
2010-07-29  88.06 113.62  77.70
2010-07-30  84.63 112.44  80.37
2010-08-02  85.99 116.35  77.67
2010-08-03  86.41 110.96  78.06
2010-08-04  84.84 113.34  76.80
2010-08-05  84.56 113.97  77.19
2010-08-06  86.24 115.62  77.16
2010-08-09  85.42 114.04  78.51
2010-08-10  87.68 111.68  75.87
> as.xts(x,order.by=as.POSIXct(index(x)))
                    USDJPY EURJPY AUDJPY
2010-07-28 09:00:00  85.17 115.83  75.43
2010-07-29 09:00:00  88.06 113.62  77.70
2010-07-30 09:00:00  84.63 112.44  80.37
2010-08-02 09:00:00  85.99 116.35  77.67
2010-08-03 09:00:00  86.41 110.96  78.06
2010-08-04 09:00:00  84.84 113.34  76.80
2010-08-05 09:00:00  84.56 113.97  77.19
2010-08-06 09:00:00  86.24 115.62  77.16
2010-08-09 09:00:00  85.42 114.04  78.51
2010-08-10 09:00:00  87.68 111.68  75.87

・・・コードがワンライナーじゃないのであまり好みではないが・・・

次はzooオブジェクトを介さないで、データフレーム型の行名として日付を突っ込んでやる方法。
まぁ素直かな?

> y <- read.csv(file.currency.rate)
> rownames(y) <- y[,1]
> as.xts(y[,-1])
           USDJPY EURJPY AUDJPY
2010-07-28  85.17 115.83  75.43
2010-07-29  88.06 113.62  77.70
2010-07-30  84.63 112.44  80.37
2010-08-02  85.99 116.35  77.67
2010-08-03  86.41 110.96  78.06
2010-08-04  84.84 113.34  76.80
2010-08-05  84.56 113.97  77.19
2010-08-06  86.24 115.62  77.16
2010-08-09  85.42 114.04  78.51
2010-08-10  87.68 111.68  75.87


最後はもっと簡単で元のデータファイルをいじっておく方法で、実はこれが一番良いと思っている。
ファイルのいじり方は簡単(日付をあらかじめ+1しておくとかではなく!!!)。
元のファイルのヘッダーのDateを削除したものを新しくCURRENCYRATE_2.csvとして以下のアドレスに用意したんで、興味あれば見てみてください。
本当にヘッダーの一個目を抜いただけです。
この対策は要するに「元データを行名付きのdata.frameとして読み込んで、それをxtsにする」っていうもの。

> file.currency.rate <- "http://dl.dropbox.com/u/9923352/CURRENCYRATE_2.csv"
> as.xts(read.csv(file.currency.rate))
           USDJPY EURJPY AUDJPY
2010-07-28  85.17 115.83  75.43
2010-07-29  88.06 113.62  77.70
2010-07-30  84.63 112.44  80.37
2010-08-02  85.99 116.35  77.67
2010-08-03  86.41 110.96  78.06
2010-08-04  84.84 113.34  76.80
2010-08-05  84.56 113.97  77.19
2010-08-06  86.24 115.62  77.16
2010-08-09  85.42 114.04  78.51
2010-08-10  87.68 111.68  75.87


こんなもんでいかがでしょうか?