Try catch en R

Introducción a R Control de flujo
Función tryCatch() 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