たぶん,前のページを読んだ人は,「なぜ fread を使わないのだ」と,怒りに震えていることだろうwww
> library(data.table)
> system.time(dat1 <- read.csv("aq"))
ユーザ システム 経過
44.938 1.164 45.952
に対して
> system.time(dat2 <- fread("aq"))
Read 15300000 rows and 6 (of 6) columns from 0.266 GB file in 00:00:05
f 6) columns from 0.266 GB file in 00:00:05
ユーザ システム 経過
4.785 0.131 4.856
なので,10倍速い。AWK なんていうものも,及びが付かない(当たり前だ。AWK はインタプリタでしかも数値も内部では文字として保持しているのだから)。
key を設定しておくといろいろ便利なこともあるが,しておかなくても十分高速だ。
> system.time(setkey(dat2, Month))
ユーザ システム 経過
0.538 0.025 0.559
「データテーブル[i, j, その他いろいろな引数]」という書式で,かなりのデータ処理が出来る。
しかも,「by reference」でやるので,余計なメモリを使わない。by reference(参照渡し) は,プログラム言語をやった人は知っている人が多い。関数に引数をわたすとき,call by value と call by reference の区別がある。普通の R 関数は call by value(値渡し) で引数を受けるので,関数内部で値を変更しても,呼び出した側の値は変わらない。大元を変えるためには,関数の戻り値を代入してやらないといけない。そんなこんなで,メモリも(コピーを含む)処理時間もコストがかかる。call by reference は,メモリ番地を引き渡すので,ある番地を書き換えたら,大元が書き換わる(というか,大元しかないのだが)。
なんやかやいったけど,結局何がいいたいかといえば,「以下のようにすれば,高速処理が出来る」。
> system.time(print(dat2[, list(m=mean(Temp), s=sd(Temp)), by=Month]))
Month m s
1: 5 65.54839 6.743403
2: 6 79.10000 6.487682
3: 7 83.90323 4.245338
4: 8 83.96774 6.478172
5: 9 76.90000 8.215231
ユーザ システム 経過
0.281 0.015 0.284
また,dplyr というやつを使えば,(好き嫌いはあるが)以下のようにして,ある程度高速処理ができる。
> library(dplyr)
> system.time(dat2 %>% group_by(Month) %>% summarize(m=mean(Temp), s=sd(Temp)) %>% print)
Source: local data table [5 x 3]
Month m s
(int) (dbl) (dbl)
1 5 65.54839 6.743403
2 6 79.10000 6.487682
3 7 83.90323 4.245338
4 8 83.96774 6.478172
5 9 76.90000 8.215231
ユーザ システム 経過
0.397 0.046 0.431
しかし,そんなことしなくてもねぇ!
data.frame で split,sapply を使って,Month ごとの Temp の平均値と標準偏差を計算してみても,結構速い。2,3倍遅いと言っても,これだけの計算を1秒未満でやれているのだから,無問題。
> system.time(print(sapply(split(dat1$Temp, dat1$Month), function(x) c(m=mean(x), s=sd(x)))))
5 6 7 8 9
m 65.548387 79.100000 83.903226 83.967742 76.900000
s 6.743403 6.487682 4.245338 6.478172 8.215231
ユーザ システム 経過
0.929 0.129 1.041
お勧めは,入力だけは fread でさっさと済ませて,あとは慣れ親しんだdata.frame で処理する。
data.table は setDF で data.frame に,by reference で変換できる(as.data.frame を使う例を示している人が多いけど,as.data.frame では,by value なのでね)。
> class(dat2)
[1] "data.table" "data.frame"
> setDF(dat2)
> class(dat2)
[1] "data.frame"
data.frame に読み込むには,data.table=FALSE オプションをつければよい(これも,言及している人が少ない。オンラインヘルプを隅から隅まで読めば,目から鱗がポロポロ落ちる...ということもあるものだ)。
> system.time(dat3 <- fread("aq", data.table=FALSE))
Read 15300000 rows and 6 (of 6) columns from 0.266 GB file in 00:00:06
f 6) columns from 0.266 GB file in 00:00:06
ユーザ システム 経過
4.903 0.153 4.950
> class(dat3)
[1] "data.frame"
逆に data.frame を data.table にするには,setDT を使う。
> class(dat1)
[1] "data.frame"
> setDT(dat1)
> class(dat1)
[1] "data.table" "data.frame"
最新の画像[もっと見る]
- 算額(その2135) 11時間前
- 算額(その2134) 18時間前
- 算額(その2133) 1日前
- 算額(その2132) 3日前
- 算額(その2131) 4日前
- 算額(その2130) 4日前
- 算額(その2129) 5日前
- 算額(その2128) 5日前
- 算額(その2127) 6日前
- 算額(その2126) 6日前
※コメント投稿者のブログIDはブログ作成者のみに通知されます