我查看了很多文档并完成了大量的Google搜索,但无法找到以下问题的答案:是否有办法在并行{{1}中引入“类似下一个”的功能使用foreach
包进行循环?
具体来说,我想做一些事情(这不适用于foreach
但没有):
next
我意识到我可以嵌套我的括号,但如果我想在长循环中有一些下一个条件,这很快就会成为语法噩梦。
这里是否有一个简单的解决方法(下一个类似功能或处理问题的不同方式)?
答案 0 :(得分:12)
您可以将代码放入函数中并调用return
。在n %% 3
时,您的示例中不清楚您希望它执行什么操作,因此我将返回NA
。
funi <- function(i) {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) return(NA)
n
}
foreach(i = 1:10, .combine = "c") %dopar% { funi(i) }
答案 1 :(得分:9)
虽然看起来很奇怪,但你可以在foreach循环体中使用return
,而不需要辅助函数(如@Aaron所示):
r <- foreach(i = 1:10, .combine='c') %dopar% {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) return(NULL)
n
}
此示例中返回NULL
,因为它被c
函数过滤掉了,这可能很有用。
此外,尽管它对您的示例不起作用,但when
函数有时可以取代next
,并且对于防止计算完全有用: / p>
r <- foreach(i=1:5, .combine='c') %:%
foreach(j=1:5, .combine='c') %:%
when (i != j) %dopar% {
10 * i + j
}
内部表达式仅被计算20次,而不是25次。这对于嵌套的foreach循环特别有用,因为when
可以访问所有上游迭代器值。
更新
如果要在列表中返回结果时过滤掉NULL
,则需要编写自己的组合功能。这是一个完整的示例,演示了一个类似于默认组合函数的组合函数,但它包含一个过滤机制:
library(doSNOW)
cl <- makeSOCKcluster(3)
registerDoSNOW(cl)
filteredlist <- function(a, ...) {
values <- list(...)
c(a, values[! sapply(values, is.null)])
}
r <- foreach(i=1:200, .combine='filteredlist', .init=list(),
.multicombine=TRUE) %dopar% {
# filter out odd values of i
if (i %% 2) return(NULL)
i
}
请注意,当有超过100个任务结果时,此代码可以正常工作(100是.maxcombine
选项的默认值。)