与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)
。
每个ID有大约4,800个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)。
并行执行并不能节省我希望的时间。这告诉我,此操作的“慢”部分不在计算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)
答案是否会改变?我对以这种嵌套循环并行化的“正确”方式特别感兴趣,尽管我确信之前已经在这个网站上进行过覆盖。
答案 0 :(得分:-1)
根据评论,我对开销的怀疑是错误的。内部函数执行需要约7微秒,而.007 * 4800 = 33.6秒。
关于:
与plyr :: dlply的split-apply-combine似乎效率低,因为拆分和组合需要开销。我错了,还是有更好/更快的方式?
答案是
事实上,我错了。如果没有让内部功能更快,那么期待严重的加速可能是不合理的。