xtsへのコンバート
※xtsの使い方自体はxtsライブラリを使ってみるー1、xtsライブラリを使ってみるー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
こんなもんでいかがでしょうか?