xtsパッケージで時系列解析
DESCRIPTION
Presentation document at Tokyo.R meeting on 2nd July 2011. Rのxts(zoo)パッケージで時系列を捌くためのノウハウ(データ作成、便利関数)を紹介。TRANSCRIPT
xts パッケージで時系列解析
@teramonagi
第15回R勉強会@東京(Tokyo.R#15)2011/07/02 1
アジェンダ自己紹介xts パッケージって?xts の作り方xts で時系列処理
2
自己紹介
3
Coming soon !
4
Coming soon !
ID:teramonagi (hatena/twitter/gmail)
職業:クオントゥ興味: .NET, 関数型言語 数理+Code+Bussiness =???
自己紹介
5
xts パッケージって?
6
xts パッケージ||
時系列を処理するための便利パッケージ
7
R には時系列の class が…
CRAN Task View: Time Series Analysis より
8
結構ある
CRAN Task View: Time Series Analysis より
9
何を使えばよいのやら
10
そんな時の xts パッケージeXtensible Time Seriesベースは zoo オブジェクト便利な関数がいっぱい他クラスへの(からの)変換
制御が容易機能拡張が容易
11
そんな時の xts パッケージeXtensible Time Seriesベースは zoo オブジェクト便利な関数がいっぱい他クラスへの(からの)変換
制御が容易機能拡張が容易
12
xts の作り方
13
使用するデータ偽日経 225 データをご用意 (http://dl.dropbox.com/u/9923352/mikkei225.csv)
> x <- read.csv("http://dl.dropbox.com/u/9923352/mikkei225.csv")> str(x)'data.frame': 118 obs. of 5 variables: $ date : Factor w/ 118 levels "2011-01-04","2011-01-05",..: 1 2 3 4 5 6 7 8 9 10 ... $ open : num 10353 10388 10477 10505 10483 ... $ height: num 10410 10413 10530 10549 10537 ... $ low : num 10322 10358 10477 10502 10475 ... $ close : num 10398 10380 10529 10540 10509 …
14
いざ xts へ! (data.frame)
> install.packages(xts)> library(xts)> as.xts(x) 以下にエラー as.POSIXlt.character(x, tz, ...) : character string is not in a standard unambiguous format> xts(x) 以下にエラー xts(x) : order.by requires an appropriate time-based object
15
(;´Д`)
※as.xts, xts 関数でも引数をちゃんと書けばいけますが、面倒… 16
いざ xts へ! (data.frame)
> x.xts <-
as.xts(read.zoo(x))> class(x.xts)[1] "xts" "zoo"> str(x.xts)An ‘xts’ object from 2011-01-04 to 2011-06-27 containing: Data: num [1:118, 1:4] 10353 10388 10477 10505 10483 ... - attr(*, "dimnames")=List of 2 ..$ : NULL ..$ : chr [1:4] "open" "height" "low" "close" Indexed by objects of class: [Date] TZ: Original class: 'zoo' xts Attributes: NULL
17
Data.frame を xtsにしたい時は一旦zoo オブジェクトを経由するのが楽
18
いざ xts へ! (csv)
> url <- "http://dl.dropbox.com/u/9923352/mikkei225.csv"> x.xts <- as.xts(read.zoo(url, header = TRUE, sep = ","))> head(x.xts) open height low close2011-01-04 10352.58 10409.56 10321.67 10398.492011-01-05 10387.55 10413.05 10357.61 10380.372011-01-06 10477.09 10529.68 10477.09 10529.332011-01-07 10505.29 10549.28 10501.59 10539.612011-01-11 10482.92 10536.69 10474.59 10508.982011-01-12 10563.10 10577.33 10503.78 10513.62
19
いざ xts へ! (matrix)> y <- matrix(1:20, ncol = 2)> z <- Sys.Date() - 1:10> x <- xts(y, order.by = z)> head(x) [,1] [,2]2011-06-19 10 202011-06-20 9 192011-06-21 8 182011-06-22 7 172011-06-23 6 162011-06-24 5 15
20
いざ xts へ! (matrix)> y <- matrix(1:20, ncol = 2)> z <- Sys.Date() - 1:10> rownames(y) <- as.character(z)> x <- as.xts(y)> head(x) [,1] [,2]2011-06-19 10 202011-06-20 9 192011-06-21 8 182011-06-22 7 172011-06-23 6 162011-06-24 5 15
21
xts で時系列処理
22
関数の紹介 (coredata, index)データ・日付だけ抜く
> head(index(x.xts))[1] "2011-01-04" "2011-01-05" "2011-01-06" "2011-01-07" "2011-01-11"[6] "2011-01-12"
> head(coredata(x.xts)) open height low close[1,] 10352.58 10409.56 10321.67 10398.49[2,] 10387.55 10413.05 10357.61 10380.37[3,] 10477.09 10529.68 10477.09 10529.33[4,] 10505.29 10549.28 10501.59 10539.61[5,] 10482.92 10536.69 10474.59 10508.98[6,] 10563.10 10577.33 10503.78 10513.62 23
time関数も可
裏を返すとデータだけ、日付だけの
変更が可能24
発想としてはこんな感じ
元になるデータ(vector or matrix)
元になる日時(Date,POSIXlt, yearmon… )
xts Object
25
日付だけ変更(型変換、1秒加算)> y <- x.xts> indexClass(y)[1] "Date"
> last(index(y))[1] "2011-06-27"
> index(y) <- as.POSIXct(index(y)) + 1> indexClass(y)[1] "POSIXt" "POSIXct"
> last(index(y))[1] "2011-06-27 09:00:01 JST"
代わりにend(start)関数も使用可
26
関数の紹介 ([, ])インデクサ ( 数値 or 日付っぽ
い文字列 ) でデータ抽出> x.xts[1:3] open height low close2011-01-04 10352.58 10409.56 10321.67 10398.492011-01-05 10387.55 10413.05 10357.61 10380.372011-01-06 10477.09 10529.68 10477.09 10529.33
> x.xts['2011-06-22::'] open height low close2011-06-22 9524.545 9657.915 9524.545 9628.7252011-06-23 9559.177 9653.867 9554.757 9598.1972011-06-24 9625.949 9694.609 9608.759 9678.2292011-06-27 9632.905 9637.475 9569.565 9577.295 27
x.xts[‘2011-06‘]で6月だけのデータ
関数の紹介 (apply.xxx)xxx(yearly,monthly…) 毎の集
計 ( 最大・最小・ lambda exp…)> apply.monthly(x.xts, max) 以下にエラー dimnames(x) <- dn : 'dimnames' の長さ [2] が配列の大きさと違っています > apply.monthly(x.xts, function(y)sapply(y, max)) open height low close2011-01-31 10594.733 10621.843 10566.553 10591.0332011-02-28 10882.025 10890.715 10819.595 10855.9802011-03-31 10732.936 10770.456 10672.576 10753.6962011-04-28 9773.167 9849.207 9718.147 9849.2072011-05-31 9963.861 10016.941 9935.741 10003.6712011-06-27 9709.612 9722.292 9660.872 9721.172
28
複数列のデータの場合は、 sapply(or apply(,2,)) をかま
せろ!29
apply.xxx 関数で足りない時apply.xxx は以下しかない
apply.daily(x, FUN, ...)apply.weekly(x, FUN, ...)apply.monthly(x, FUN, ...)apply.quarterly(x, FUN, ...)apply.yearly(x, FUN, ...)
分、あるいはもっと小さい単位のマイクロ秒データを束にして処理したい時もある
30
関数の紹介 (endpoints, period.apply)組み合わせて強力な集計が可能
> ep <- endpoints(x.xts, on = "months")> period.apply(x.xts, ep, function(x_)sapply(x_, max)) open height low close2011-01-31 10594.733 10621.843 10566.553 10591.0332011-02-28 10882.025 10890.715 10819.595 10855.9802011-03-31 10732.936 10770.456 10672.576 10753.6962011-04-28 9773.167 9849.207 9718.147 9849.2072011-05-31 9963.861 10016.941 9935.741 10003.6712011-06-27 9709.612 9722.292 9660.872 9721.172
31
関数の紹介 (endpoints, period.apply)組み合わせて強力な集計が可能
> ep <- endpoints(x.xts, on = "months", k = 3)> period.apply(x.xts, ep, function(x_)sapply(x_, max)) open height low close2011-03-31 10882.025 10890.71 10819.595 10855.982011-06-27 9963.861 10016.94 9935.741 10003.67
32
関数の紹介 (split)データをある時間単位で list 化
> x.xts.June <- x.xts["2011-06"]> split(x.xts.June, "weeks")[[1]] open height low close2011-06-01 9709.612 9722.292 9660.872 9721.1722011-06-02 9560.639 9575.019 9517.289 9555.0492011-06-03 9551.175 9603.615 9491.265 9492.7952011-06-06 9467.313 9490.493 9359.723 9380.293[[2]] open height low close2011-06-07 9373.654 9457.104 9360.754 9445.394 33
週ごとに list化
zoo パッケージ関数も適用可関数のローリング適
用 :rollapply
各青矢印の期間で統計量算出
元の時系列データ
34
zoo パッケージ関数も適用可関数のローリング適
用 :rollapply> tail(rollapply(x.xts, 100, mean)) open height low close2011-04-05 9905.609 9961.785 9836.091 9898.2462011-04-06 9896.647 9952.923 9827.107 9889.4112011-04-07 9888.149 9944.702 9818.797 9881.0572011-04-08 9879.627 9936.826 9810.408 9873.0092011-04-11 9871.232 9928.818 9802.288 9865.0142011-04-12 9862.969 9920.402 9794.668 9857.194
100(日)平均を計算
35
zoo パッケージ関数も適用可まとめて捌く :aggregate
> aggregate(x.xts, as.yearmon, last) open height low close1 2011 10219.885 10265.865 10182.475 10237.8252 2011 10504.552 10628.772 10448.842 10624.1023 2011 9764.651 9765.181 9658.011 9754.4714 2011 9748.827 9849.207 9712.047 9849.2075 2011 9500.721 9697.471 9497.521 9693.8516 2011 9632.905 9637.475 9569.565 9577.295
各月の月末値を抽出
36
zoo パッケージ関数も適用可欠損値の補間 : na.approx, na.spline> y.xts <- aggregate(x.xts, as.yearmon,
last)> y.xts[3,1] <- NA > y.xts open height low close1 2011 10219.885 10265.865 10182.475 10237.8252 2011 10504.552 10628.772 10448.842 10624.102
3 2011 NA 9765.181 9658.011 9754.4714 2011 9748.827 9849.207 9712.047 9849.2075 2011 9500.721 9697.471 9497.521 9693.8516 2011 9632.905 9637.475 9569.565 9577.295
37
zoo パッケージ関数も適用可欠損値の補間 : na.approx, na.spline> na.approx(y.xts)
open height low close1 2011 10219.885 10265.865 10182.475 10237.8252 2011 10504.552 10628.772 10448.842 10624.1023 2011 10126.690 9765.181 9658.011 9754.471> na.spline(y.xts) open height low close1 2011 10219.885 10265.865 10182.475 10237.8252 2011 10504.552 10628.772 10448.842 10624.1023 2011 10207.079 9765.181 9658.011 9754.471
線形補間
スプライン補間
38
zoo パッケージ関数も適用可欠損値の補間 : na.locf
> na.locf(y.xts) open height low close1 2011 10219.885 10265.865 10182.475 10237.8252 2011 10504.552 10628.772 10448.842 10624.102
3 2011 10504.552 9765.181 9658.011 9754.4714 2011 9748.827 9849.207 9712.047 9849.2075 2011 9500.721 9697.471 9497.521 9693.8516 2011 9632.905 9637.475 9569.565 9577.295
1つ前の値(1行前の値)で補間
39
その他便利関数Xts 同士の結合 (merge, rbind)
日時 Obj で範囲抽出(window)
欠損値補間 (na.aggregate)xts のままにする (Reclass)
40
まとめxts = eXtensible Time
Seriesベースは zoo オブジェクト月ごとの集計等複雑な時系列処
理もサクサク書ける詳しく知りたかったら CRAN のzoo, xts の Manual 読め
41
まとめstackoverflow の [r],[time-series]
も good
42