R foreach中的函数无法识别列表

时间:2016-04-11 23:02:57

标签: r

我试图在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

与标准的不一致。任何的想法 ?

1 个答案:

答案 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)