考虑对数据框执行标准的分组操作:
您可以想象,在循环中需要每个包和对象时,需要使用自己的
library(plyr)
library(doMC)
library(MASS) # for example
nc <- 12
registerDoMC(nc)
d <- data.frame(x = c("data", "more data"), g = c("group1", "group2"))
y <- "some global object"
res <- ddply(d, .(g), function(d_group) {
# slow, complicated operations on d_group
}, .parallel = FALSE)
只需简单地将.parallel=TRUE写入代码中,就可以轻松利用多核设置。这是plyr中我最喜欢的功能之一。
但由于plyr已被弃用(我想),并且基本上被dplyr、purrr等替代,因此并行处理的解决方案变得更加冗长:
library(dplyr)
library(multidplyr)
library(parallel)
library(MASS) # for example
nc <- 12
d <- tibble(x = c("data", "more data"), g = c("group1", "group2"))
y <- "some global object"
cl <- create_cluster(nc)
set_default_cluster(cl)
cluster_library(cl, packages = c("MASS"))
cluster_copy(cl, obj = y)
d_parts <- d %>% partition(g, cluster = cl)
res <- d_parts %>% collect() %>% ungroup()
rm(d_parts)
rm(cl)
您可以想象,在循环中需要每个包和对象时,需要使用自己的
cluster_*
命令将其复制到节点上,因此这个示例可能会变得非常长。未并行化的plyr-to-dplyr转换只是一个简单的dplyr::group_by
构造,不幸的是,没有一种简洁的方法来启用并行处理。因此,我的问题是:
- 这实际上是从plyr转换到dplyr的首选方式吗?
- 在plyr背后发生了什么神奇的事情,使得轻松开启并行处理成为可能?是否有任何原因导致将此功能添加到dplyr特别困难,因此它还不存在?
- 我的两个示例在代码执行方面基本上有什么不同?
partition()
,会发生与之前相同的魔法:plyr
依赖于以前注册的foreach
后端(print(plyr ::: setup_parallel)
),没有群集的multidplyr :: partition()
隐式地依赖于create_cluster()
,但可能会检测到另一个已经注册的后端(尽管我没有检查,请参见print(multidplyr ::: cluster_exists))
。multidplyr
手册的第一个示例说明了这种仅需调用partition()
而无需进行先前设置的能力。 - Aurèlemultidplyr
不像plyr
那样允许分叉,只能使用PSOCK
。 - Aurèle