Подтвердить что ты не робот

Затем с пакетом 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
}

Я понимаю, что могу вложить свои скобки, но если я хочу иметь несколько следующих условий в длинном цикле, это очень быстро становится синтаксическим кошмаром.

Есть ли простой способ обхода (как следующая функция или другой способ решения проблемы)?

4b9b3361

Ответ 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).