2012-03-12 20 views
6

Estoy tratando de usar el paquete foreach en un bucle anidado, pero mi bucle interno no reconoce el contador externo, ¿qué me falta?Variable de bucle externo en el bucle foreach anidado R

v3 <- search.compounds.by.mass(100.05,0.5) 
foreach(j=2:length(v2)) %:% { 
    foreach(i=1:length(v3), .combine=rbind) %dopar% { 
     write.table(paste(v3[i], paste(get.reactions.by.compound(v3[i]), collapse=" "), sep=" "), "file1",quote=FALSE, row.names=FALSE, col.names=FALSE, append=TRUE) 
     write.table(paste(v3[i], paste(get.pathways.by.compounds(v3[i]), collapse=" "), sep=" "), "file2",quote=FALSE, row.names=FALSE, col.names=FALSE, append=TRUE) 
     v3 <- search.compounds.by.mass(v2[j],0.5) 
    } 
} 
+0

¿Cuál es el mensaje de error? Además, lo que está en la variable v2 (puede usar dput (v2) para que podamos reproducirlo) –

Respuesta

16

El problema es que se está aplicando de forma incorrecta el operador %:%. Está diseñado para fusionar dos objetos foreach, lo que da como resultado un único objeto foreach que se puede usar para evaluar repetidamente cualquier expresión que le proporcione. Por lo tanto, si desea utilizar %:%, es necesario primera fusionar las dos foreach() declaraciones, y luego utilizar el objeto resultante para conducir una sola llamada a %do% (o, en su caso, %dopar%). Ver (1) a continuación para un ejemplo.

Alternativamente, si desea anidar los dos foreach() objetos, utilice %do% dos veces, como en (2) a continuación.

De cualquier manera funciona, aunque para trabajos paralelos, yo podría preferir el que usa %:%. Su código, sin embargo, como (3) a continuación, combina elementos de las dos estrategias para producir un híbrido que no puede hacer nada.

X <- c("A", "B") 
Y <- 1:3 

## (1) EITHER merge two 'foreach' objects using '%:%' ... 
foreach (j = X, .combine = c) %:% foreach(i = Y, .combine = c) %do% { 
    paste(j, i, sep = "") 
} 
# [1] "A1" "A2" "A3" "B1" "B2" "B3" 


## (2) ... OR Nest two 'foreach' objects using a pair of '%do%' operators ... 
foreach(j = X, .combine = c) %do% { 
    foreach(i = Y, .combine = c) %do% { 
     paste(j, i, sep = "") 
    } 
} 
# [1] "A1" "A2" "A3" "B1" "B2" "B3" 


## (3) ... BUT DON'T use a hybrid of the approaches. 
foreach(j = X, .combine = c) %:% { 
    foreach(i = Y, .combine = c) %do% { 
     paste(j, i, sep = "") 
    } 
} 
# Error in foreach(j = X, .combine = c) %:% { : 
# "%:%" was passed an illegal right operand 
+0

Hola Josh, gracias por tu respuesta, ¡funcionó ahora! – user1265067

+2

Bueno para escuchar. Por cierto, si quiere leer más sobre algunas de las decisiones involucradas en cómo estructurar bucles anidados, escriba 'vignette (" anidado ")' en la línea de comando R. –

+1

Es doloroso observar que la viñeta muestra la forma correcta de hacerlo, y explícitamente dice que es un operador binario, pero es tan fácil cometer este error. –

Cuestiones relacionadas