R在内部循环返回矩阵的嵌套的foreach循环

问题描述:

我想并行我有一个for循环。有问题的循环内有一个嵌套循环,我想并行化。答案必定非常类似于:nested foreach loops in R to update common array,但我似乎无法使其起作用。我已经尝试了所有我能想到的选项,包括将内部循环转换为自己的函数并对其进行并行化处理,但我一直收到空列表。R在内部循环返回矩阵的嵌套的foreach循环

第一,非的foreach示例工作:

theFrame <- data.frame(col1=rnorm(100), col2=rnorm(100)) 

theVector <- 2:30 

regFor <- function(dataFrame, aVector, iterations) 
{ 
    #set up a blank results matrix to save into. 
    results <- matrix(nrow=iterations, ncol=length(aVector)) 

    for(i in 1:iterations) 
    { 
     #set up a blank road map to fill with 1s according to desired parameters 
     roadMap <- matrix(ncol=dim(dataFrame)[1], nrow=length(aVector), 0) 
     row.names(roadMap) <- aVector 
     colnames(roadMap) <- 1:dim(dataFrame)[1] 

     for(j in 1:length(aVector)) 
     { 
      #sample some of the 0s and convert to 1s according to desired number of sample 
      roadMap[j,][sample(colnames(roadMap),aVector[j])] <- 1 
     } 

     temp <- apply(roadMap, 1, sum) 

     results[i,] <- temp 
    } 

    results <- as.data.frame(results) 
    names(results) <- aVector 

    results 
} 

test <- regFor(theFrame, theVector, 2) 

但是这和我的其他类似的尝试不起作用。

trying <- function(dataFrame, aVector, iterations, cores) 
{ 
    registerDoMC(cores) 

    #set up a blank results list to save into. i doubt i need to do this 
    results <- list() 

    foreach(i = 1:iterations, .combine="rbind") %dopar% 
    { 
     #set up a blank road map to fill with 1s according to desired parameters 
     roadMap <- matrix(ncol=dim(dataFrame)[1], nrow=length(aVector), 0) 
     row.names(roadMap) <- aVector 
     colnames(roadMap) <- 1:dim(dataFrame)[1] 

     foreach(j = 1:length(aVector)) %do% 
     { 
      #sample some of the 0s and convert to 1s according to desired number of sample 
      roadMap[j,][sample(colnames(roadMap),aVector[j])] <- 1 
     } 

     results[[i]] <- apply(roadMap, 1, sum) 
    } 
    results 
} 

test2 <- trying(theFrame, theVector, 2, 2) 

我认为我不得不在内部循环中使用foreach,不管怎样,对吧?

使用的foreach,你从来没有“建立一个空白的结果列表保存到”,你嫌。相反,您将评估foreach循环体的结果组合起来,并返回组合结果。在这种情况下,我们希望外部foreach循环将矢量(由内部foreach循环计算)按行逐行组合到矩阵中。该矩阵被分配给变量results,然后转换为数据帧。

这是我在您的转换例如第一次尝试:

library(doMC) 

foreachVersion <- function(dataFrame, aVector, iterations, cores) { 
    registerDoMC(cores) # unusual, but reasonable with doMC 
    rows <- nrow(dataFrame) 
    cols <- length(aVector) 
    results <- 
    foreach(i=1:iterations, .combine='rbind') %dopar% { 
     # The value of the inner foreach loop is returned as 
     # the value of the body of the outer foreach loop 
     foreach(aElem=aVector, .combine='c') %do% { 
     roadMapRow <- double(length=rows) 
     roadMapRow[sample(rows,aElem)] <- 1 
     sum(roadMapRow) 
     }  
    } 
    results <- as.data.frame(results) 
    names(results) <- aVector 
    results 
} 

内环不需要被实现为foreach循环。您也可以使用sapply,但我会试着找出是否有更快的方法。但对于这个答案,我想演示一个foreach方法。我使用的唯一真正的优化是通过在内部foreach循环内执行sum来摆脱对apply的调用。

+0

谢谢!这很好。如果不清楚,我的实际代码在两个循环内部都会做更复杂的事情,所以使用sapply等可能会非常棘手。我的原始配方有两个主要问题。首先是建立一个空白列表并试图保存结果(顺便说一下,在其他情况下,我已经成功完成了foreach),第二个并没有理解.combine正在做什么的含义。这很酷,并且可以生成结果,而无需使用像Reduce()这样的事情,这是我在过去用foreach完成的。谢谢! – forlooper 2015-02-25 21:00:26

+0

@forlooper在foreach循环中可能会产生副作用,但取决于您使用的后端,它的工作方式会有所不同,因此强烈建议您不要这样做。我最初试图防止在foreach中出现副作用的可能性,但我最终放弃了尝试。 – 2015-02-25 22:02:01

+0

谢谢史蒂夫。我想我应该重新编程一些东西! – forlooper 2015-02-27 19:05:48

你需要把结果的foreach的一个变量:

results<- foreach(... 
+0

这是问题的关键。谢谢!史蒂夫韦斯顿的上面答案是对这个问题的完整答案。 – forlooper 2015-02-25 20:53:35

+0

然后标记他的答案为你的答案,并请投票。 – cmbarbu 2015-02-25 20:59:49

+0

对不起,我点击了第一个错误的符号。我现在修好了。再次感谢。 – forlooper 2015-02-25 21:47:00