dplyrとdata.tableを比べてみた

グループごとの計算は tapply, by, aggregate, plyrパッケージなどがありますが、どれも遅い。最近はもっぱらdata.tableを使っているのですが、最近出たパッケージdplyrが速いらしい、ということでdata.tableとdplyrのスピードを比較してみました。

5群データごとに平均値を計算する処理をします。

値とグループの2列のデータフレームを用意します。

> N <- 10000000

> x <- data.table(x=rnorm(N), b=factor(sample(letters[1:5], N, rep=T)))
>

まずはtapply

>
> # tapply
> system.time(
+ y.ta <- tapply(x$x, x$b, mean)
+ )
   ユーザ   システム       経過 
      4.49       0.11       4.65
> print(y.ta)
            a             b             c             d             e
 2.609237e-04  2.778484e-04  1.077809e-06 -1.022228e-03 -1.078577e-03
>

次にdata.table

> # data.table
> x1 <- data.table(x, key="b")
> system.time(
+ y.dt <-x1[, mean(x), key=b]
+ )
   ユーザ   システム       経過 
      0.18       0.01       0.20
> print(y.dt)
   b            V1
1: a  2.609237e-04
2: b  2.778484e-04
3: c  1.077809e-06
4: d -1.022228e-03
5: e -1.078577e-03
>

やはり、速い。

最後にdplyr

> #dplyr
> system.time(
+ y.dp <- (x %.%
+ group_by(b) %.%
+ summarise(m=mean(x)))
+ )
   ユーザ   システム       経過 
      0.41       0.07       0.48
> print(y.dp)
Source:     local data table [5 x 2]

  b             m
1 a  2.609237e-04
2 b  2.778484e-04
3 c  1.077809e-06
4 d -1.022228e-03
5 e -1.078577e-03

あれ?期待していたほどじゃないですね。

data.tableが一番速い結果となりました。

列数を変えたら変わりそうな気がしますが

とりあえずここまで。暇があったら検証してみます。

 

> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: i386-w64-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932  
[3] LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                 
[5] LC_TIME=Japanese_Japan.932   

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base    

other attached packages:
[1] dplyr_0.1.2      data.table_1.9.2

loaded via a namespace (and not attached):
[1] assertthat_0.1 plyr_1.8.1     Rcpp_0.11.0    reshape2_1.2.2 stringr_0.6.2
[6] tools_3.0.2