Переменная внешнего цикла во вложенном цикле R foreach - PullRequest
7 голосов
/ 13 марта 2012

Я пытаюсь использовать пакет foreach во вложенном цикле, но мой внутренний цикл не распознает внешний счетчик, что я пропустил?

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)
    }
}

1 Ответ

16 голосов
/ 13 марта 2012

Проблема в том, что вы неправильно используете оператор %:%.Он предназначен для объединения двух foreach объектов, в результате чего получается один foreach объект, который можно использовать для многократной оценки любого выражения, которое вы ему предоставляете.Итак, если вы хотите использовать %:%, вам нужно сначала объединить два оператора foreach(), а затем использовать полученный объект для передачи одного вызова %do%(или в вашем случае %dopar%).См. (1) ниже для примера.

В качестве альтернативы, если вы хотите вложить два объекта foreach(), используйте %do% дважды, как в (2) ниже.

В любом случае работает, хотядля параллельных заданий я бы предпочел тот, который использует %:%.Ваш код, как и (3) ниже, объединяет элементы двух стратегий для создания гибрида, который ничего не может сделать.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...