r - 将嵌套的for循环转换为R中的并行

标签 r foreach parallel-processing parallel-foreach

您可以在下面找到一段 R 中的代码,我想将其转换为使用多个 CPU 的并行进程运行。我尝试使用 foreach包,但没有走多远.. 鉴于我有 3 级嵌套循环,我找不到如何使它工作的好例子。帮助将不胜感激。下面的代码示例 - 我做了一个简单的函数,所以它可以作为一个例子:

celnum <- c(10,20,30)
t2 <- c(1,2,3)
allrepeat <- 10

samplefunction <- function(celnum,t2){

        x <- rnorm(100,celnum,t2)
        y = sample(x, 1)
        z = sample(x,1)

        result = y+z


        result 
}

常规方式获取结果:
z_grid <- matrix(, nrow = length(celnum), ncol = length(t2))

repetitions <- matrix(, nrow = allrepeat, ncol = 1)



set.seed=20
for(i in 1:length(celnum)){
        for (j in 1:length(t2)){
                for (k in 1:allrepeat) {
                        results <- samplefunction(celnum[i],t2[j]) 
                                repetitions[k] <- results
                                z_grid[i,j] <- mean(repetitions,na.rm=TRUE) 
                }  
        }
}

z_grid

现在尝试使用 foreach 做同样的事情:
set.seed=20

library(foreach)
library(doSNOW)

cl <- makeCluster(3, type = "SOCK")
registerDoSNOW(cl)

set.seed=20
output <- foreach(i=1:length(celnum),.combine='cbind' ) %:% 
        foreach (j=1:length(t2), .combine='c') %:%   
                foreach (k = 1:allrepeat) %do% {
                        mean(samplefunction(celnum[i],t2[j]) )
}  
output

这不像我希望的那样工作,因为它返回一个 30x2 维度的矩阵,而不是 3x3。我的目的是模拟 i 和 j 组合 k 次的场景,并希望为 i 和 j 的每个组合获得这些 k 次模拟的平均值。

最佳答案

编辑:

嵌套的 for 循环应如下所示。请注意,只有一个 foreach 和两个 for 循环嵌套。

library(foreach)
library(doSNOW)

cl <- makeCluster(3, type = "SOCK")
registerDoSNOW(cl)

set.seed(20)
output <- foreach(k=1:allrepeat) %dopar% {
  df <- data.frame()
  for (i in 1:length(t2)) {
    for (j in 1:length(celnum)) {
      df[i,j] <- mean(samplefunction(celnum[i],t2[j]))
    }  
  }
  df
}

结果 output 也是 list 。计算单元格意味着 this post 有很大帮助。
library(plyr)
aaply(laply(output, as.matrix), c(2,3), mean)

#   X2
# X1       V1       V2       V3
#  1 20.30548 21.38818 18.49324
#  2 40.09506 40.64564 40.34847
#  3 60.10946 59.68913 58.66209

顺便说一句:你应该...
stopCluster(cl)

... 然后。

原帖:

首先,您必须确定要将哪个 for 循环替换为 foreach 循环。

基本上,这个决定主要受循环结果的影响,因此,如何组合这些结果。由于您将单个进程外包给 PC 的各个处理器,因此只会返回最后一个元素。这些结果将按照 .combine 参数(例如 'c''cbind' 等)中的说明进行组合。由于您正在尝试生成 两个 列表,因此第一次开始可能不是很容易。因此,我想提出一个示例,概述嵌套在其他 foreach 循环中的 for 循环的功能。
library(foreach)
library(doSNOW)

dat1 <- c(15.2, 12.58, 4.25, 1.05, 6.78, 9.22, 11.20)
dat2 <- data.frame(matrix(1:15, ncol = 3))


cl <- makeCluster(3, type = "SOCK")
registerDoSNOW(cl)

for (i in 1:nrow(dat2)) {
  FEresult <- foreach(j = 1:ncol(dat2), .combine = c, .inorder = TRUE) %dopar% {
    tmp <- dat1 * dat2[i, j]
    data.frame(tmp)
  }
  FEresult
  if (i == 1) {
    res <- FEresult
  } else {
    res <- rbind(res, FEresult)
  }
}

res

你会注意到,这个循环的结果是一个列表。

关于r - 将嵌套的for循环转换为R中的并行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38568645/

相关文章:

c - MPI - 段错误退出代码 : 139

r - 如何向具有 4 个子图的 R 图添加值

r - 除了 na.rm= TRUE 之外,mean 还返回 NaN

r - 获取 "mlm"返回的 `lm()`对象的残差标准错误

r - 在Windows上并行运行ddply()的简单工作示例

hadoop - hadoop是在单个计算机上管理数据批处理的可行解决方案吗?

使用 ajax 的 jQuery UI 自动完成,其源是使用 foreach 从文本文件生成的

c++ - Boost.Bind 以访问 std::for_each 中的 std::map 元素

java - 如何从jSTL中的foreach循环获取索引值

parallel-processing - 用于混合分布式和共享内存的混合 OpenMP + OpenMPI?