2015-02-05 14 views
7

Ich würde gerne wissen, ob es möglich wäre, zwei verschiedene Objekte nach der Verwendung foreach%dopar% Schleife ausgeben.outptut zwei Objekte mit foreach

Ich werde versuchen zu erklären, was ich suche. Nehmen wir an, ich habe zwei data.frames als Folge von mehreren Operationen innerhalb der Schleife:

library(doMC) 
library(parallel) 
registerDoMC(cores=4) 

result <- foreach(i=1:100) %dopar% { 
#### some code here 
#### some code here 
vec1 <- result_from_previous code # It would be the 1st object I'd like to ouput 
vec2 <- result_from_previous code # It would be the 2nd object I'd like to output 
} 

Meine gewünschte Ausgabe wäre eine Liste von data.frames der Länge 2, wie sein:

dim(result[[1]]) # equals to nrow=length(vec1) and ncol=100 
dim(result[[2]]) # equals to nrow=length(vec2) and ncol=100 

ich habe mit dieser aus einem früheren Beitrag versucht Saving multiple outputs of foreach dopar loop:

comb <- function(x, ...) { 
    lapply(seq_along(x), function(i) c(x[[i]], lapply(list(...), function(y) y[[i]]))) 

result <- foreach(i=1:100, .comb='comb', .multicombine=TRUE) %dopar% { 
#### some code here 
#### some code here 
vec1 <- result_from_previous code 
vec2 <- result_from_previous code 
list(vec1, vec2) 
} 

Aber es gibt nicht das erwartete Ergebnis

Wenn ich Folgendes tun:

result <- foreach(i=1:100, .comb=cbind) %dopar% { 
#### some code here 
#### some code here 
vec1 <- result_from_previous code 
vec2 <- result_from_previous code 
} 

ich erhalten nur die data.frame von vec2. Gibt es eine Möglichkeit, beide Ausgänge zurückzugeben oder zu speichern?

Dank

Antwort

10

Wenn Sie zwei Objekte aus dem Körper der foreach-Schleife zurückkommen müssen, müssen Sie sie in ein Objekt irgendwie oder andere bündeln und eine Liste ist der üblicher Weg, das zu tun. Der Trick besteht darin, eine geeignete Kombinationsfunktion bereitzustellen, um das gewünschte Endergebnis zu erzielen. Wenn Sie alle vec1 Objekte mit cbind und auch alle vec2 Objekte mit cbind kombinieren möchten, ist die mapply Funktion ziemlich praktisch. Ich denke, das ist das, was Sie wollen:

comb <- function(...) { 
    mapply('cbind', ..., SIMPLIFY=FALSE) 
} 

Hier ist ein kleines Testprogramm für diese kombinieren Funktion:

result <- foreach(i=1:100, .combine='comb', .multicombine=TRUE) %dopar% { 
    vec1 <- rep(i, 10) 
    vec2 <- rep(2*i, 10) 
    list(vec1, vec2) 
} 

Diese Liste zurück, die zwei, 10 X 100 Matrizen, aber die gleiche Funktion kombinieren kann verwendet werden, wenn vec1 und vec2 Datenrahmen sind.