parallel - ¿Siguiente con el paquete foreach de Revolution R?
parallel package r (2)
He revisado gran parte de la documentación y he hecho una buena cantidad de Google, pero no puedo encontrar una respuesta a la siguiente pregunta: ¿Hay una manera de inducir la funcionalidad ''siguiente-como'' en un bucle foreach
paralelo utilizando el paquete foreach
?
Específicamente, me gustaría hacer algo como (esto no funciona con el next
pero no lo hace):
foreach(i = 1:10, .combine = "c") %dopar% {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) {next}
n
}
Me doy cuenta de que puedo anidar mis corchetes, pero si quiero tener algunas de las siguientes condiciones en un bucle largo, esto se convierte rápidamente en una pesadilla de sintaxis.
¿Hay una solución sencilla aquí (ya sea la siguiente funcionalidad similar o una manera diferente de abordar el problema)?
Aunque parezca extraño, puede usar un return
en el cuerpo de un bucle foreach, sin la necesidad de una función auxiliar (como lo demuestra @Aaron):
r <- foreach(i = 1:10, .combine=''c'') %dopar% {
n <- i + floor(runif(1, 0, 9))
if (n %% 3) return(NULL)
n
}
En este ejemplo, se devuelve un valor NULL
ya que se elimina mediante la función c
, lo que puede ser útil.
Además, aunque no funciona bien en su ejemplo, la función when
puede reemplazar al next
en algunas ocasiones, y es útil para evitar que el cálculo tenga lugar en absoluto:
r <- foreach(i=1:5, .combine=''c'') %:%
foreach(j=1:5, .combine=''c'') %:%
when (i != j) %dopar% {
10 * i + j
}
La expresión interna solo se evalúa 20 veces, no 25. Esto es particularmente útil con bucles foreach anidados, ya que when
tiene acceso a todos los valores del iterador ascendente.
Actualizar
Si desea filtrar NULL
s al devolver los resultados en una lista, necesita escribir su propia función de combinación. Aquí hay un ejemplo completo que muestra una función de combinación que funciona como la función de combinación predeterminada pero incluye un mecanismo de filtrado:
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
}
Tenga en cuenta que este código funciona correctamente cuando hay más de 100 resultados de tareas (100 es el valor predeterminado de la opción .maxcombine
).
Usted podría poner su código en una función y return
llamada. No queda claro en su ejemplo lo que quiere que haga cuando n %% 3
así que le devolveré 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) }