我试图在R中使用并行计算,但是我遇到了一些麻烦。
首先,我生成一个由物种和时间组成的列表,如下所示
df <- data.frame(species = rep(c(1:100), each = 100), time = runif(10000,150, 1008))
species <- unique(df$species)
然后我运行以下代码来获得一种步骤函数的总和
#standard
ntw <- function(now){
L2 <- 0
for (Ii in species){
time <- subset(df, subset = species == Ii)$time
time <- sort(time)
L2 <- L2 + stepfun(time,seq(0,length(time)))(now)
}
return(L2)
}
尝试
> ntw(152)
[1] 27
到目前为止一直很好,现在我加载doParallel并尝试使用并行计算复制相同的东西:
library(doParallel)
library(foreach)
cl <- makeCluster(2)
registerDoParallel(cl)
#parallel
nt <- function(now){
L2 <- 0
foreach(i = species,.combine = rbind) %dopar% {
time <- subset(df, subset = species ==i)$time
time <- sort(time)
L2 <- L2 + stepfun(time,seq(0,length(time)))(now)
}
return(L2)
}
尝试
> nt(152)
Error in { : task 1 failed - "could not find 'df'"
不明白发生了什么。
更新: 根据@ chinsoon12和@brittenb的建议,我使用以下代码指定导出
#parallel
nt <- function(now){
L2 <- 0
foreach(i = species,.combine = rbind,.export = "df") %dopar% {
time <- subset(df, subset = species ==i)$time
time <- sort(time)
L2 <- L2 + stepfun(time,seq(0,length(time)))(now)
}
return(L2)
}
现在尝试
> nt(152)
[1] 0
与标准的不一致。任何的想法 ?
答案 0 :(得分:1)
你必须得到foreach
的返回值,在你的情况下是rbind
每次调用stepfun
的结果的数组构建:
nt <- function(now){
result <- foreach(i = species,.combine = "rbind", .export = "df") %dopar% {
time <- subset(df, subset = species ==i)$time
time <- sort(time)
stepfun(time,seq(0,length(time)))(now)
}
return(sum(result))
}
nt(152)
[1] 28
这里的一个重大错误是尝试并行地为L2分配值:您尝试通过不同的流程同时为同一个变量分配多个值...
你也可以使用"+"
组合器更简单地重写一下:
nt <- function(now){
foreach(i = species,.combine = "+", .export = "df") %dopar% {
time <- subset(df, subset = species ==i)$time
time <- sort(time)
stepfun(time,seq(0,length(time)))(now)
}
}
nt(152)
[1] 28
(*)为了更好的重现性,使用随机性时总是包含set.seed(xxx)