【发布时间】:2014-08-15 06:31:03
【问题描述】:
短版
Split-apply-combine 与 plyr::dlply 似乎效率低下,因为拆分和合并需要开销。我错了,还是有更好/更快的方法?
长版
我在 R 中使用一个类似于 vars::VAR 的美化包装器/提取器的函数来拟合数千个向量自回归。我就叫它estim。
现在,我的数据是“长”格式,例如
dd <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 3L), time = c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L,
4L), x = c(0L, 0L, 1L, 0L, 6L, 2L, 3L, 2L, 3L, 3L, 1L, 1L), y = c(0L,
1L, 1L, 0L, 2L, 0L, 2L, 0L, 0L, 3L, 3L, 0L)), .Names = c("id",
"time", "x", "y"), row.names = c(NA, -12L), class = "data.frame")
我正在使用output <- plyr::dlply(dd, .(id), myFun) 处理。
有了大约 4,800 个唯一 ID,每个 ID 有 182 个时间点,我得到了
system.time(output <- plyr::dlply(dd, .(id), estimate, .parallel = FALSE))
# user system elapsed
# 37.357 0.730 38.048
和
registerDoMC(detectCores() - 1) # I have 4 cores
system.time(output <- plyr::dlply(dd, .(id), estimate, .parallel = TRUE))
# user system elapsed
# 57.234 6.710 23.593
在我的 MacBook(2.8 GHz i7 和 16 GB RAM)上。
并行执行并没有像我希望的那样节省时间。这向我表明,此操作的“慢”部分不在于计算 estimate,而在于 dplyr 采用的拆分和组合步骤。
split-apply-combine 范式非常适合交互式和中等规模的使用(至少在这种情况下比循环快得多),但我怀疑还有更好的方法。我是否应该将数据重塑为“宽”格式,例如
dd.wide <- structure(list(time = 1:4, `1_x` = c(0L, 0L, 1L, 0L), `1_y` = c(0L,
1L, 1L, 0L), `2_x` = c(6L, 2L, 3L, 2L), `2_y` = c(2L, 0L, 2L,
0L), `3_x` = c(3L, 3L, 1L, 1L), `3_y` = c(0L, 3L, 3L, 0L)), .Names = c("time",
"1_x", "1_y", "2_x", "2_y", "3_x", "3_y"), row.names = c(NA,
-4L), class = "data.frame")
然后将myFun 应用于成对的列?
有没有更有效的方法来实现这一点?或者,我可以在这里更好地利用并行化吗?还是会达到预期的速度?
最后,让我们说现在我想做的事
estim2 <- function(param) ddply(dd, .(id), estim, foo = param)
output.list <- lapply(1:10, estim2)
答案是否完全改变?我对并行化这种嵌套循环的“正确”方法特别感兴趣,尽管我确信这个网站之前已经介绍过。
【问题讨论】:
-
"dplyr 使用的拆分和组合步骤" 用 dplyr 而不是 plyr(您现在正在使用的软件包)尝试这个怎么样?我更喜欢 data.table,但 dplyr is 比 plyr 快得多。如果您要求性能建议,您应该提供可重现的代码并创建您正在处理的规模的数据。
-
@Roland: + 1 for data.table
-
我也喜欢 data.table(和 dplyr),但我可以让它返回一个任意列表吗?我对两者都很陌生。
-
让你的问题成为一个可重复的例子,我估计你会在 15 分钟内知道你是否可以做你想做的事(以及可能如何以不同的方式完成) )。
-
正如@Roland 和其他人所指出的,您的答案完全取决于您使用的功能。在 4 个内核上获得 2 倍的加速听起来是合理的,因为至少有一部分时间花在了内核之间的通信和整理结果的开销上。您目前的解决方案每个 id 大约需要 5 微秒。你希望它快多少?无论如何,这个级别的微调取决于减少流程每个步骤的低效率。发布一个完全可重现的示例。
标签: r performance data-structures plyr