Затем с пакетом Revolution R foreach?
Я просмотрел большую часть документации и сделал довольно много Googling, но не могу найти ответ на следующий вопрос: есть ли способ вызвать функцию "next-like" в параллельном foreach
с помощью пакета foreach
?
В частности, я хотел бы сделать что-то вроде этого (это не работает с next
, но без него):
foreach(i = 1:10, .combine = "c") %dopar% {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) {next}
n
}
Я понимаю, что могу вложить свои скобки, но если я хочу иметь несколько следующих условий в длинном цикле, это очень быстро становится синтаксическим кошмаром.
Есть ли простой способ обхода (как следующая функция или другой способ решения проблемы)?
Ответы
Ответ 1
Вы можете поместить свой код в функцию и вызвать 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) }
Ответ 2
Хотя кажется странным, вы можете использовать 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
имеет доступ ко всем значениям итератора восходящего потока.
Update
Если вы хотите отфильтровать 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
).