2012-03-12 19 views
6

Próbuję użyć pakietu foreach w zagnieżdżonej pętli, ale moja wewnętrzna pętla nie rozpoznaje zewnętrznego licznika, czego mi brakuje?Zmienna pętli zewnętrznej w zagnieżdżonej pętli foreach 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

Co to jest komunikat o błędzie? Co jest w zmiennej v2 (możesz użyć dput (v2), abyśmy mogli ją odtworzyć) –

Odpowiedz

16

Problemem jest to, że są nieprawidłowo stosując operator %:%. Został zaprojektowany w celu scalenia dwóch obiektów foreach, co daje w wyniku pojedynczy obiekt, który może być używany do wielokrotnego oceniania dowolnego wyrażenia, które do niego dodajesz. Tak więc, jeśli chcesz używać %:%, trzeba pierwszy scalić dwa foreach() sprawozdań i następnie wykorzystywać obiekt wynikowy do kierowania jednego połączenia do %do% (lub w przypadku, %dopar%). Zobacz poniżej przykład (1).

Ewentualnie, jeśli chcesz gnieździe dwa foreach() obiekty, użyj %do% dwukrotnie, podobnie jak w (2) poniżej.

Tak czy inaczej, ale dla zadań równoległych wolę ten, który używa %:%. Twój kod, podobnie jak poniżej: (3), łączy elementy obu strategii, tworząc hybrydę, która nie może nic zrobić.

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

Cześć Josh, dziękuję za odpowiedź, która zadziałała! – user1265067

+2

Dobrze słyszeć. Przy okazji, jeśli chcesz przeczytać więcej o niektórych decyzjach związanych ze strukturowaniem zagnieżdżonych pętli, wpisz 'vignette (" nested ")' w linii poleceń R. –

+1

To bolesne, że winieta pokazuje właściwą drogę, i wyraźnie stwierdza, że ​​jest operatorem binarnym, ale tak łatwo jest popełnić ten błąd. –