dena76 dena76 - 22 days ago 7
R Question

R - Register the Errors as a new Variable/Vector/Column

I am learning the basics of R and I am currently using tryCatch to continue a loop even when an error is encountered. It basically looks like this:

for (variableloop in (1:10000)){

tryCatch({

My function/ formula goes here

},error=function(e){cat("ERROR :",conditionMessage(e), "\n")})
}


I was wondering if there is a command to save up the list of cases where the loop provided an error.

Thank you very much for your time.

Answer

What you want is to for each call to your function to return both the result and the error, where exactly one of the two is empty. Something like this (using base R):

# bigger loop than this ...
input <- 1:5
myfunc <- function(ign) if ( (x <- runif(1)) < 0.2) stop(paste0("some error: ", x)) else x

set.seed(2)
ret <- lapply(input, function(i) {
  tryCatch(list(result = myfunc(i), error = NA),
           error = function(e) list(result = NA, error = e))
})
str(ret)
# List of 5
#  $ :List of 2
#   ..$ result: logi NA
#   ..$ error :List of 2
#   .. ..$ message: chr "some error: 0.18488225992769"
#   .. ..$ call   : language myfunc(i)
#   .. ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ :List of 2
#   ..$ result: num 0.702
#   ..$ error : logi NA
#  $ :List of 2
#   ..$ result: num 0.573
#   ..$ error : logi NA
#  $ :List of 2
#   ..$ result: logi NA
#   ..$ error :List of 2
#   .. ..$ message: chr "some error: 0.168051920365542"
#   .. ..$ call   : language myfunc(i)
#   .. ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ :List of 2
#   ..$ result: num 0.944
#   ..$ error : logi NA

You can access just the (possibly empty) errors with:

str(lapply(ret, `[[`, "error"))
# List of 5
#  $ :List of 2
#   ..$ message: chr "some error: 0.18488225992769"
#   ..$ call   : language myfunc(i)
#   ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ : logi NA
#  $ : logi NA
#  $ :List of 2
#   ..$ message: chr "some error: 0.168051920365542"
#   ..$ call   : language myfunc(i)
#   ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ : logi NA

You can also use the purrr package:

set.seed(2)
ret <- lapply(input, function(i) {
  purrr::safely(myfunc)(i)
})
str(lapply(ret, `[[`, "error"))
# List of 5
#  $ :List of 2
#   ..$ message: chr "some error: 0.18488225992769"
#   ..$ call   : language .f(...)
#   ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ : NULL
#  $ : NULL
#  $ :List of 2
#   ..$ message: chr "some error: 0.168051920365542"
#   ..$ call   : language .f(...)
#   ..- attr(*, "class")= chr [1:3] "simpleError" "error" "condition"
#  $ : NULL