关于你的data.table
解决方案,你不需要set key用于聚合操作。您可以直接执行:
indexVars = paste0('f', 1:4, sep = '')
dtDup <- as.data.table(dfDup) ## faster than data.table(.)
dtDupAgg = dtDup[, list(data = sum(data)), by = c(indexVars)]
data.table
1.9.2+版本还实现了一个功能setDT
这使得能够转换data.frames
to data.tables
引用(这意味着没有副本,因此转换几乎不需要时间,对于大型数据帧尤其有用)。
因此,不要这样做:
dtDup <- as.data.table(dfDup)
dtDup[...]
你可以这样做:
## data.table v1.9.2+
setDT(dfDup) ## faster than as.data.table(.)
dfDup[...] ## dfDup is now a data.table, converted by reference
关于你的第一个问题,plyr
不以其速度而闻名。查看为什么plyr这么慢? https://stackoverflow.com/questions/11533438/why-is-plyr-so-slow(以及那里的许多信息丰富的评论)了解更多信息。
也许您可能感兴趣dplyr
,这比plyr
,但仍然慢于data.table
, 恕我直言。这是等效的dplyr
版本:
dfDup %.% group_by(f1, f2, f3, f4) %.% summarise(data = sum(data))
这是之间的基准data.table
and dplyr
数据(所有计时均为连续三次运行的最小值):
## data.table v1.9.2+
system.time(ans1 <- dtDup[, list(data=sum(data)), by=c(indexVars)])
# user system elapsed
# 0.049 0.009 0.057
## dplyr (commit ~1360 from github)
system.time(ans2 <- dfDup %.% group_by(f1, f2, f3, f4) %.% summarise(data = sum(data)))
# user system elapsed
# 0.374 0.013 0.389
我实在是没有耐心去跑plyr
版本(首次运行 93 秒后停止)。如你看到的dplyr
比plyr
,但比慢约 7 倍data.table
here.
检查结果是否相等以确保:
all.equal(as.data.frame(ans1[order(f1,f2,f3,f4)]),
as.data.frame(ans2))
# [1] TRUE
HTH