接下来是Revolution R的foreach包吗?

时间:2011-10-10 00:12:56

标签: r foreach parallel-processing next

我查看了很多文档并完成了大量的Google搜索,但无法找到以下问题的答案:是否有办法在并行{{1}中引入“类似下一个”的功能使用foreach包进行循环?

具体来说,我想做一些事情(这不适用于foreach但没有):

next

我意识到我可以嵌套我的括号,但如果我想在长循环中有一些下一个条件,这很快就会成为语法噩梦。

这里是否有一个简单的解决方法(下一个类似功能或处理问题的不同方式)?

2 个答案:

答案 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选项的默认值。)