Хотя это кажется странным, вы можете использовать return
в теле цикла foreach, без необходимости во вспомогательной функции (как продемонстрировал @Aaron):
r <- foreach(i = 1:10, .combine='c') %dopar% {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) return(NULL)
n
}
A NULL
возвращается в этом примере, поскольку оно отфильтровывается функцией c
, что может быть полезно.
Кроме того, хотя для вашего примера это не очень хорошо работает, функция when
может иногда заменять next
и полезна для предотвращения вычислений вообще:
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
s при возврате результатов в списке, вам нужно написать собственную функцию объединения. Вот полный пример, который демонстрирует функцию объединения, которая работает как функция объединения по умолчанию, но включает в себя механизм фильтрации:
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
).