dplyrは列数に影響を受けない

plyrとdoByをきちんと検証した素晴らしい記事がある。
http://gg-hogehoge.hatenablog.com/entry/2014/01/04/143733
dplyrがインストールできないとのことなので、dplyrも加えて検証した。

結果


dplyrが圧倒的だった。
本当はplyrは列数が増えるとなぜ遅くなるのかとかRProf使って検証すべきなんだけど、dplyrが圧倒的だったのでやめた。

参考

dplyrはRcpp使ってplyrを書き直してるっぽい。
https://github.com/hadley/dplyr/blob/master/src/RcppExports.cpp

以下、コード。

# 参考文献: 
# http://gg-hogehoge.hatenablog.com/entry/2014/01/04/143733
library(plyr)
library(doBy)
library(dplyr)
library(ggplot2)
library(reshape2)
set.seed(42)

# データフレームの作成
types <- c("A","B","C","D","E")
obs <- 4e+06
dat <- data.frame(type = as.factor(sample(types, obs, replace=TRUE)))

# データフレームの列数を増やしながら, 処理時間を計測
Nmax <- 10
plyr_time <- 0
doBy_time <- 0
dplyr_time <- 0

for (N in 1:Nmax){
  dat[,N+1] <- round(runif(obs, min=0, max = 1), digits = 2)
  names(dat)[N+1] <- paste("value", N, sep="")
  print(object.size(dat), units ="MB")
  
  plyr_time[N] <- system.time(
    plyr_res <- ddply(dat, .(type), summarize, 
                      mean_percent = mean(value1))
  )[3]
  doBy_time[N] <- system.time(
    doBy_res <- summaryBy(value1 ~ type, data = dat, FUN = mean)
  )[3]
  dplyr_time[N] <- system.time(
    dplyr_res <- summarise(group_by(dat, type), mean(value1))
  )[3]
  
}

# 結果をデータフレームに格納してggplotする
res <- data.frame(plyr=plyr_time, doBy=doBy_time, dplyr=dplyr_time)
res <- melt(res)
res$colsize <- rep(2:(Nmax+1), 3)
names(res) <- c("method", "time", "col.size")
ggplot(data = res, aes(x=col.size, y = time, col=method)) + 
  geom_line(size = 1) +
  geom_point(size = 5) +
  ggtitle("plyr vs doBy vs dplyr") + 
  theme(text=element_text(size=16)) + 
  ylab("time (sec)")