在Foreach循环中修改变量?

时间:2013-02-15 20:51:20

标签: r foreach parallel-processing

我正在尝试构建一个并行的for-each循环,它修改了两个矩阵。我在开始循环之前创建并初始化矩阵。这是一个虚拟程序,演示了我的代码应该如何工作。程序执行时没有错误,但是在foreach循环结束后矩阵仍然为空。注意:这是我的代码的简化版本,而不是实际的代码本身。

#Assume that I've loaded parallel and doParallel and that my computer has 2+ cores 
cluster <- makeCluster(detectCores())
registerDoParallel(cluster)
a1 <- array(dim=c(9,9))
a2 <- array(dim=c(9,9))
numbers <- 1:18
foreach (i=1:9, .combine='c') %dopar%{
    a1[i,] = numbers[1:9]
    a2[i,] = numbers[10:18]
}
stopCluster(cluster)

为什么这个程序不会填充a1和a2的行?

编辑:我在以前的任何帖子中找不到我的问题的答案。 C#和Perl有类似的线程,但没有一个与R.

有关

2 个答案:

答案 0 :(得分:3)

您不能使用foreach来执行此类副作用。循环中的赋值发生在工作进程中,故意不发送回主服务器。你为它的返回值执行foreach,所以如果你想生成两个矩阵,foreach应该返回一个包含两个矩阵的列表。

这是一个使用combine函数从worker列表中构建多个矩阵的示例:

rcomb <- function(...) {
  args <- list(...)
  lapply(seq_along(args[[1]]), function(i)
         do.call('rbind', lapply(args, function(a) a[[i]])))
}

numbers <- 1:18
m <- foreach (i=1:9, .combine='rcomb', .multicombine=TRUE) %dopar% {
    list(numbers[1:9], numbers[10:18])
}

尽管rcomb有点复杂,但它可以处理任意数量的矩阵,并且可以通过许多任务结果调用,这对于效率原因很重要。

答案 1 :(得分:0)

也许这有帮助。无法测试,请原谅错误。

 require(snowfall)

sfInit(cpus=2,parallel=TRUE)

a1 <- matrix(NA,ncol=9,nrow=0)
a2 <- matrix(NA,ncol=9,nrow=0)
numbers <- 1:18

a1 = rbind(a1,sfSapply(1:9,function(x) return(numbers[1:9]), numbers))
a2 = rbind(a2,sfSapply(1:9,function(x) return(numbers[10:18]), numbers))

sfStop()