Qualcuno ha esempi / tutorial sulla gestione delle eccezioni in R? La documentazione ufficiale è molto concisa.
Qualcuno ha esempi / tutorial sulla gestione delle eccezioni in R? La documentazione ufficiale è molto concisa.
Risposte:
Oltre alla risposta di Shane che ti punta ad altre discussioni StackOverflow, potresti provare una funzione di ricerca del codice. Questa risposta originale indicava la ricerca del codice di Google da allora è stata interrotta, ma puoi provare
Solo per la cronaca, c'è anche try
ma tryCatch
potrebbe essere preferibile. Ho provato un conteggio veloce in Google Code Search, ma try ottiene troppi falsi positivi per il verbo stesso, ma sembra che tryCatch
sia più ampiamente utilizzato.
Fondamentalmente vuoi usare la tryCatch()
funzione. Guarda help ("tryCatch") per maggiori dettagli.
Ecco un esempio banale (tieni presente che puoi fare quello che vuoi con un errore):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Dai un'occhiata a queste domande correlate:
Questo risultato di una ricerca Google correlata mi ha aiutato: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
La funzione trycatch()
è abbastanza semplice e ci sono molti buoni tutorial su questo. Un'eccellente spiegazione della gestione degli errori in R può essere trovata nel libro Advanced-R di Hadley Wickham , e ciò che segue è un'introduzione molto semplice withCallingHandlers()
e withRestarts()
con il minor numero di parole possibile:
Diciamo che un programmatore di basso livello scrive una funzione per calcolare il valore assoluto. Non sa bene come calcolarlo, ma sa come costruire un errore e trasmette diligentemente la sua ingenuità:
low_level_ABS <- function(x){
if(x<0){
#construct an error
negative_value_error <- structure(
# with class `negative_value`
class = c("negative_value","error", "condition"),
list(message = "Not Sure what to with a negative value",
call = sys.call(),
# and include the offending parameter in the error object
x=x))
# raise the error
stop(negative_value_error)
}
cat("Returning from low_level_ABS()\n")
return(x)
}
Un programmatore di medio livello scrive anche una funzione per calcolare il valore assoluto, facendo uso della low_level_ABS
funzione tristemente incompleta . Sa che il codice di basso livello genera un negative_value
errore quando il valore di x
è negativo e suggerisce una soluzione al problema, stabilendo una restart
che consente agli utenti di mid_level_ABS
di controllare il modo in cui si mid_level_ABS
risolve (o non si) da un negative_value
errore.
mid_level_ABS <- function(y){
abs_y <- withRestarts(low_level_ABS(y),
# establish a restart called 'negative_value'
# which returns the negative of it's argument
negative_value_restart=function(z){-z})
cat("Returning from mid_level_ABS()\n")
return(abs_y)
}
Infine, un programmatore di alto livello utilizza la mid_level_ABS
funzione per calcolare il valore assoluto e stabilisce un gestore di condizioni che dice al gestore
mid_level_ABS
di recuperare da un negative_value
errore utilizzando il gestore di riavvio.
high_level_ABS <- function(z){
abs_z <- withCallingHandlers(
# call this function
mid_level_ABS(z) ,
# and if an `error` occurres
error = function(err){
# and the `error` is a `negative_value` error
if(inherits(err,"negative_value")){
# invoke the restart called 'negative_value_restart'
invokeRestart('negative_value_restart',
# and invoke it with this parameter
err$x)
}else{
# otherwise re-raise the error
stop(err)
}
})
cat("Returning from high_level_ABS()\n")
return(abs_z)
}
Il punto di tutto questo è che utilizzando withRestarts()
e withCallingHandlers()
, la funzione è
high_level_ABS
stata in grado di dire mid_level_ABS
come recuperare da errori generati da low_level_ABS
errore senza interrompere l'esecuzione di
mid_level_ABS
, cosa che non puoi fare con tryCatch()
:
> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
In pratica, low_level_ABS
rappresenta una funzione che mid_level_ABS
chiama molte (forse anche milioni di volte), per la quale il metodo corretto di gestione degli errori può variare a seconda della situazione, e la scelta di come gestire errori specifici è lasciata alle funzioni di livello superiore ( high_level_ABS
).
La funzione di riavvio è molto importante in R ereditato da Lisp. È utile se si desidera chiamare una funzione nel corpo del ciclo e si desidera solo che il programma continui se la chiamata alla funzione si interrompe. Prova questo codice:
for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a),
finally = print("loop body finished!")),
abort = function(){})