¿Alguien tiene ejemplos / tutoriales de manejo de excepciones en R? La documentación oficial es muy concisa.
¿Alguien tiene ejemplos / tutoriales de manejo de excepciones en R? La documentación oficial es muy concisa.
Respuestas:
Además de la respuesta de Shane que le indica otras discusiones de StackOverflow, puede probar una función de búsqueda de código. Esta respuesta original apuntaba a la búsqueda de código de Google desde entonces ha sido descontinuada, pero puede intentar
Solo para que conste, también existe, try
pero tryCatch
puede ser preferible. Probé un conteo rápido en Google Code Search, pero el intento obtiene demasiados falsos positivos para el verbo en sí, pero parece que tryCatch
se usa más ampliamente.
Básicamente quieres usar la tryCatch()
función. Consulte la ayuda ("tryCatch") para obtener más detalles.
Aquí hay un ejemplo trivial (tenga en cuenta que puede hacer lo que quiera con un error):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Eche un vistazo a estas preguntas relacionadas:
Este resultado de una búsqueda relacionada en Google me ayudó: http://biocodenv.com/wordpress/?p=15 .
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
La función trycatch()
es bastante sencilla y hay muchos buenos tutoriales sobre eso. Se puede encontrar una excelente explicación del manejo de errores en R en el libro Advanced-R de Hadley Wickham , y lo que sigue es una introducción muy básica withCallingHandlers()
y withRestarts()
en la menor cantidad de palabras posible:
Digamos que un programador de bajo nivel escribe una función para calcular el valor absoluto. No está seguro de cómo calcularlo, pero sabe cómo construir un error y transmite diligentemente su ingenuidad:
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 programador de nivel medio también escribe una función para calcular el valor absoluto, haciendo uso de la low_level_ABS
función lamentablemente incompleta . Sabe que el código de bajo nivel arroja un negative_value
error cuando el valor de x
es negativo y sugiere una solución al problema, al establecer un código restart
que permite a los usuarios de mid_level_ABS
controlar la forma en que se mid_level_ABS
recupera (o no) de un negative_value
error.
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)
}
Por último, un programador de alto nivel usa la mid_level_ABS
función para calcular el valor absoluto y establece un controlador de condición que le dice al
mid_level_ABS
que se recupere de un negative_value
error usando el controlador de reinicio.
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)
}
El punto de todo esto es que al usar withRestarts()
y withCallingHandlers()
, la función
high_level_ABS
fue capaz de decir mid_level_ABS
cómo recuperarse de los errores generados por low_level_ABS
error sin detener la ejecución de
mid_level_ABS
, que es algo que no se puede hacer 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
En la práctica, low_level_ABS
representa una función que mid_level_ABS
llama mucho (quizás incluso millones de veces), por lo que el método correcto de manejo de errores puede variar según la situación, y la elección de cómo manejar errores específicos se deja a funciones de nivel superior ( high_level_ABS
).
La función de reinicio es muy importante en R heredado de Lisp. Es útil si desea llamar a alguna función en el cuerpo del bucle y solo desea que el programa continúe si la llamada a la función colapsa. Prueba este código:
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(){})