日中足のデータをxts型に倒す

むかーしに書いた記事

のやり方「as.xts(read.zoo(hoge))」だと、日中足のデータが正しく読めねぇよ!

という話を見かけたので、こんなんいかがでしょうかというお話。
日中足が問題というよりも、xtsの時間の単位が日付ではなく時刻ベースになると困るという話だと思うんで、
それっぽい適当データをDropbox上にアップしておいたので、それを参考にやる。

〜データの読込&表示〜

> library(xts)
> URL <- "http://dl.dropboxusercontent.com/u/9923352/data20140416.csv"
> x <- read.csv(URL, stringsAsFactors=FALSE)
> head(x)
            DATETIME         A        B
1 2014/4/16 19:57:01 100.00000 113.0000
2 2014/4/16 20:11:42 100.12118 113.1927
3 2014/4/16 20:26:17  99.65098 112.7743
4 2014/4/16 20:40:25  99.17331 112.3624
5 2014/4/16 20:54:28  99.03122 112.4074
> str(x)
'data.frame':	5 obs. of  3 variables:
 $ DATETIME: chr  "2014/4/16 19:57:01" "2014/4/16 20:11:42" "2014/4/16 20:26:17" "2014/4/16 20:40:25" ...
 $ A       : num  100 100.1 99.7 99.2 99
 $ B       : num  113 113 113 112 112

一応、秒単位までの時刻を持つデータであることが確認できる。

これに対して、昔書いたas.xts&read.zooの関数の組を噛ませると・・・

> as.xts(read.zoo(x))
                   A        B
2014-04-16 100.00000 113.0000
2014-04-16 100.12118 113.1927
2014-04-16  99.65098 112.7743
2014-04-16  99.17331 112.3624
2014-04-16  99.03122 112.4074
Warning message:
In zoo(rval3, ix) :
  some methods for “zoo” objects do not work if the index entries in ‘order.by’ are not unique

となって、時刻以下の情報がごっそりと削られる。これを回避するには、めんどくさいけど、以下のように時間部分とデータ部分を分離し、時間部分をPOSIXltにするといい。

> x.xts <- xts(x[,-1], strptime(x$DATETIME, "%Y/%m/%d %H:%M:%S"))
> class(x.xts)
[1] "xts" "zoo"
> head(x.xts)
                            A        B
2014-04-16 19:57:01 100.00000 113.0000
2014-04-16 20:11:42 100.12118 113.1927
2014-04-16 20:26:17  99.65098 112.7743
2014-04-16 20:40:25  99.17331 112.3624
2014-04-16 20:54:28  99.03122 112.4074

あるいはこんな書き方も可能

> x.xts <- xts(x[,-1], as.POSIXct(x$DATETIME))
> class(x.xts)
[1] "xts" "zoo"
> head(x.xts)
                            A        B
2014-04-16 19:57:01 100.00000 113.0000
2014-04-16 20:11:42 100.12118 113.1927
2014-04-16 20:26:17  99.65098 112.7743
2014-04-16 20:40:25  99.17331 112.3624
2014-04-16 20:54:28  99.03122 112.4074

as.POSIXctでもas.POSIXltでもどっちでもいいみたい。