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
的调用。
谢谢!这很好。如果不清楚,我的实际代码在两个循环内部都会做更复杂的事情,所以使用sapply等可能会非常棘手。我的原始配方有两个主要问题。首先是建立一个空白列表并试图保存结果(顺便说一下,在其他情况下,我已经成功完成了foreach),第二个并没有理解.combine正在做什么的含义。这很酷,并且可以生成结果,而无需使用像Reduce()这样的事情,这是我在过去用foreach完成的。谢谢! – forlooper 2015-02-25 21:00:26
@forlooper在foreach循环中可能会产生副作用,但取决于您使用的后端,它的工作方式会有所不同,因此强烈建议您不要这样做。我最初试图防止在foreach中出现副作用的可能性,但我最终放弃了尝试。 – 2015-02-25 22:02:01
谢谢史蒂夫。我想我应该重新编程一些东西! – forlooper 2015-02-27 19:05:48