2012-03-12 10 views
6

Sto provando a utilizzare il pacchetto foreach in un ciclo annidato, ma il mio ciclo interno non riconosce il contatore esterno, cosa mi manca?Variabile ciclo esterno nel ciclo foreach R annidato

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

Qual è il messaggio di errore? Inoltre, cosa c'è nella variabile v2 (puoi usare dput (v2) in modo che possiamo riprodurlo) –

risposta

16

Il problema è che si sta applicando in modo errato l'operatore %:%. È progettato per unire due oggetti foreach, risultando in un singolo oggetto foreach che può essere utilizzato per valutare ripetutamente qualsiasi espressione fornita dall'utente. Quindi, se si vuole utilizzare %:%, è necessario prima unire i due foreach() dichiarazioni, e poi utilizzare l'oggetto risultante di guidare una singola chiamata a %do% (o nel tuo caso, %dopar%). Vedere (1) di seguito per un esempio.

In alternativa, se si desidera nido due foreach() oggetti, utilizzare %do% due volte, come in (2) qui di seguito.

In entrambi i casi funziona, sebbene per i lavori paralleli potrei preferire quello che utilizza %:%. Il tuo codice, tuttavia, come (3) in basso, combina elementi delle due strategie per produrre un ibrido che non può fare nulla.

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

Ciao Josh, grazie per la tua risposta ha funzionato ora! – user1265067

+2

Buono a sapersi. A proposito, se vuoi leggere di più su alcune delle decisioni relative alla struttura dei cicli annidati, digita 'vignette (" nested ")' nella riga di comando R. –

+1

È doloroso notare che la vignetta mostra il modo giusto per farlo, e afferma esplicitamente che si tratta di un operatore binario, ma è così facile fare questo errore. –

Problemi correlati