2015-02-05 6 views
7

Vorrei sapere se è possibile generare due oggetti diversi dopo aver utilizzato il ciclo foreach%dopar%.outptut due oggetti utilizzando foreach

Cercherò di spiegare quello che sto cercando. Supponiamo che ho due data.frames a seguito di diverse operazioni all'interno del ciclo:

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 
} 

mio output desiderato sarebbe un elenco di data.frames di lunghezza 2, come ad esempio:

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

ho provato con questo da un post precedente 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) 
} 

Ma non dà il risultato previsto

Quando faccio la seguente:

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

io ottenere solo la data.frame di vec2. C'è un modo per restituire o salvare entrambe le uscite?

Grazie

risposta

10

Se avete bisogno di tornare due oggetti dal corpo del ciclo foreach, è necessario raggruppare in un unico oggetto un modo o nell'altro, e un elenco è il modo più generale per farlo. Il trucco è fornire una funzione di combinazione appropriata per ottenere il risultato finale desiderato. Se si desidera combinare tutti gli oggetti vec1 con cbind e anche tutti gli oggetti vec2 con cbind, la funzione mapply è piuttosto utile. Credo che questo sia ciò che si vuole:

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

Ecco un piccolo programma di test per questa funzione combinare:

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

Ciò restituirà una lista contenente due, 10 x 100 matrici, ma la stessa funzione Combina può essere utilizzato se vec1 e vec2 sono frame di dati.