2015-06-30 5 views
8

Sto cercando di utilizzare la funzione try() a che fare con gli errori che si verificano nel mio parallelised ciclo for:Problemi con prova() all'interno foreach() in R

results <- foreach (i = 1:2, .errorhandling = 'remove') %dopar% { 
    res <- try(myfun(i), TRUE) 
} 

con

myfun <- function(i){ 
    if (i==1) return(rnorm(1)) 
    else stop('error') 
} 

Viene visualizzato il seguente messaggio di errore

Error in checkForRemoteErrors(val) : 
    one node produced an error: Error in myfun(i) : error 

Come è possibile ottenere il "ciclo" foreach per ignorare il messaggio di errore (o almeno affrontarlo un po 'più elegantemente)?

risposta

5

È possibile utilizzare tryCatch e gestire l'errore in modo appropriato. Qui l'errore viene ignorato (ritorno NULL)

results <- foreach (i = 1:2) %dopar% { 
    res <- tryCatch({ 
     myfun(i) 
    }, error=function(e) NULL) 
} 

o semplicemente utilizzando il comando incorporato .errorhandling='remove' come si deve, senza il try dovrebbe rimuovere già gli errori.

6

Se si desidera utilizzare la gestione degli errori "rimuovere" o "passare" in foreach, non è necessario rilevare l'errore. Ecco i risultati nella determinazione della manipolazione a "eliminare" Errore:

> foreach (i = 1:2, .errorhandling = 'remove') %dopar% { 
+  myfun(i) 
+ } 
[[1]] 
[1] 1.314854 

qui sono i risultati quando si usano "passaggio":

> foreach (i = 1:2, .errorhandling = 'pass') %dopar% { 
+  myfun(i) 
+ } 
[[1]] 
[1] 0.7247509 

[[2]] 
<simpleError in myfun(i): error> 

Utilizzando try, l'errore viene catturata e quindi tradotti un oggetto "try-error" dalla funzione try, nascondendo l'errore da foreach fino a quando la funzione clusterApplyLB (che viene utilizzata per implementare il doParallel backend) rileva l'oggetto "try-error" nell'elenco dei risultati e genera un errore in il processo principale. Lo chiamerei un bug in doParallel.

Si noti che la soluzione fornita da @LegalizeIt funziona perché restituisce un valore NULL anziché un oggetto "try-error", evitando così il bug in doParallel.