R中的嵌套foreach循环,其中内部循环returns一个矩阵
Nested foreach loop in R where inner loop returns a matrix
我正在尝试并行化我拥有的 for 循环。有问题的循环内有一个嵌套循环,我想并行化。答案肯定非常类似于:nested foreach loops in R to update common array,但我似乎无法让它工作。我已经尝试了所有我能想到的选项,包括将内部循环变成它自己的函数并将其并行化,但我总是得到空列表。
第一个非 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的结果放在一个变量中:
results<- foreach( ...
使用 foreach 时,您绝不会 "set up a blank results list to save into",正如您所怀疑的那样。相反,您将评估 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
的调用。
- 我知道这是一个过时的问题,但只是给那些提示
谁没有得到嵌套的 foreach 来工作。
- 如果用
foreach()%dopar%{foreach()%do%{}}
并行化外循环,你会
需要在外部的扩充中包含 .packages = c("doSNOW")
循环,否则你会 运行 变成 "doSNOW not found"
错误。
- 一般来说,人们只是将内部循环并行化(
foreach()%:%foreach()%dopar%{}
,论坛上也有建议),这
对于大量数据(等待组合
每 100 个结果以及每个内部循环的末尾,这个过程不是并行的!)。
我正在尝试并行化我拥有的 for 循环。有问题的循环内有一个嵌套循环,我想并行化。答案肯定非常类似于:nested foreach loops in R to update common array,但我似乎无法让它工作。我已经尝试了所有我能想到的选项,包括将内部循环变成它自己的函数并将其并行化,但我总是得到空列表。
第一个非 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的结果放在一个变量中:
results<- foreach( ...
使用 foreach 时,您绝不会 "set up a blank results list to save into",正如您所怀疑的那样。相反,您将评估 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
的调用。
- 我知道这是一个过时的问题,但只是给那些提示 谁没有得到嵌套的 foreach 来工作。
- 如果用
foreach()%dopar%{foreach()%do%{}}
并行化外循环,你会 需要在外部的扩充中包含.packages = c("doSNOW")
循环,否则你会 运行 变成"doSNOW not found"
错误。 - 一般来说,人们只是将内部循环并行化(
foreach()%:%foreach()%dopar%{}
,论坛上也有建议),这 对于大量数据(等待组合 每 100 个结果以及每个内部循环的末尾,这个过程不是并行的!)。