考虑一下data.frame上的标准分组操作:
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被废弃(我认为)并基本上被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到dplyr转换只是一个简单的dplyr::group_by结构,不幸的是,没有简单的方法在其上启用并行处理。所以,我的问题是:
发布于 2017-12-16 13:31:32
你可以用这样的模式。
library(dplyr)
library(purrr)
library(future)
plan(multicore)
options(mc.cores = availableCores())
d <- data.frame(x = 1:8, g = c("group1", "group2", "group3", "group4"))
y <- "some global object"
split(d, d$g) %>%
map(~ future({Sys.sleep(5);mean(.x$x)})) %>%
map_df(~value(.x))..。用一些技巧对map_df步骤做一些并行处理。注意,在{purrr}下,~是匿名函数语法,其中.x是已映射到的值。
如果您喜欢危险地生活,则可以通过使用{purrr}中的私有方法来创建类似的版本,而不必使用{未来}。
mcmap <- function(.x, .f, ...) {
.f <- as_mapper(.f, ...)
mclapply(.x, function(.x) {
force(.f)
.Call(purrr:::map_impl, environment(), ".x", ".f", "list")
}) %>%
map(~ .x[[1]])
}https://stackoverflow.com/questions/47597744
复制相似问题