Try catch en R
La función tryCatch
permite capturar errores y advertencias cuando se ejecuta un código R y manejarlos de la forma que se desee. Esto te permitirá evaluar algún código cuando surja un error o una advertencia o simplemente mostrar el mensaje de error o advertencia, evitando que el código se detenga u obtengas resultados incorrectos.
Sintaxis
La sintaxis de un tryCatch
en R es la siguiente:
tryCatch(
expr = {
# Expresión a ser evaluada
},
error = function(e){
# Código para manejar el error capturado
# print(e)
},
warning = function(w){
# Código para manejar el warning capturado
# print(w)
},
finally = {
# Expresión a ser evaluada antes de acabar
}
)
El código principal va dentro de expr
, si se captura un error se evaluará el código dentro de error
y si se captura una advertencia se evaluará el código dentro de warning
. El código dentro de finally
se evaluará independientemente de si hay algún error o advertencia.
Ten en cuenta que error
, warning
y finally
son opcionales, por lo que puedes especificar uno o dos si lo prefieres.
Manejo de errores
Considera que estás escribiendo una función en la que puede surgir un error y no quieres que tu código se detenga. En esta situación tu mejor opción es usar un tryCatch
y ejecutar algún código si surge el error.
En el siguiente ejemplo estamos multiplicando el valor de entrada por dos, pero si se captura un error, el error se imprimirá, el valor de entrada será transformado a numérico y luego multiplicado por dos y devuelto.
# Función de muestra
test_fun <- function(x) {
tryCatch(
# Código a ser evaluado
expr = {
x <- x * 2
return(x)
},
# Código si se captura un error
error = function(e){
print(e)
x <- as.numeric(x) * 2
return(x)
}
)
}
Si pruebas la función con una entrada numérica, no se producirá ningún error y la función devolverá el valor multiplicado por dos:
res <- test_fun(10)
res
20
Sin embargo, si el valor de entrada es una cadena de texto, se producirá un error porque el valor no se puede multiplicar, por lo que se evaluará el código dentro de error
. El error se imprimirá, el dato de entrada se convertirá a numérico y se calculará el resultado deseado.
res <- test_fun("10")
res
<simpleError in x * 2: non-numeric argument to binary operator>
20
Si estás evaluando algún código dentro de un bucle y se produce un error el código no se detendrá si lo atrapas con tryCatch
. Ten en cuenta que puedes simplemente imprimir el error o algún mensaje para ser consciente de la iteración que ha fallado y no tomar ninguna otra acción si no quieres.
Manejo de warnings
Si la expresión evaluada puede lanzar un mensaje de advertencia y quieres atraparlo y evaluar algún código si eso ocurre puedes manejarlo con warning
.
El ejemplo siguiente es similar al anterior, pero en este caso intentamos capturar una advertencia que se produce cuando un carácter no puede ser transformado a numérico, por lo que se imprimirá el mensaje de advertencia y un mensaje personalizado y la función devolverá un NA
.
# Función de muestra
test_fun_2 <- function(x) {
tryCatch(
# Código a ser evaluado
expr = {
x <- as.numeric(x)
x <- x * 2
return(x)
},
# Código si se captura un warning
warning = function(w){
print(w)
message("Introduce un valor numérico")
return(NA)
}
)
}
Si intentas introducir un carácter que no se puede convertir en numérico (como "A"
) la función as.numeric
mostrará un mensaje de advertencia y se evaluará el código dentro de warning
.
res <- test_fun_2("A")
res
<simpleWarning in doTryCatch(return(expr), name, parentenv, handler): NAs introduced by coercion>
Input a numeric value
NA
Evaluar expressiones al final
Si quieres evaluar alguna expresión a pesar de que el código lance un error o una advertencia puedes usar finally
. En el siguiente ejemplo estamos creando una función que multiplica un número por dos y cuando el código se evalúa, se mostrará un mensaje en consola diciendo: “Listo”.
# Función de muestra
test_fun_3 <- function(x) {
tryCatch(
# Código a ser evaluado
expr = {
x <- x * 2
return(x)
},
# Código a ser evaluado antes de acabar
finally = {
message("Listo")
}
)
}
Si pruebas la función verás el resultado y el mensaje.
res <- test_fun_3(5)
res
Listo
10