Custom tryCatch(…) in R

Returning warning messages along with function results.

This weekend I spent a considerable amount of time trying to debug a code chunk consisting of a modeling function inside a for loop. The code was running through the entire loop and outputting a series of warnings at the end. And because it’s looping through a non-trivial modeling function on a sizable data, the run-time was almost an hour.

In my first debugging attempt, I changed the warnings to errors to break the code whenever there were warnings by using options(warn = 2). Note that in R warnings will only generate a message and errors will stop the code from running. The default option for warnings is options(warn = 0).

The problem with this method is that I really don’t want to have to sit in front of my computer waiting for the code to run through to the next modeling issue and break for every different warning message. It would be great if I could let the code completely run through and along with warning messages, also flag which iteration of the modeling function was causing issues.

I had written tryCatch functions before in R to return customized warnings but never had to write one that also returned the result of the function tried inside the tryCatch. The only way I could figure out how to do this was to run the modeling function twice in each iteration. Because run-time was a concern, I dug around various websites. It took longer than expected to find what I was looking for, but here it is from user2161065 on stackoverflow.

This custom tryCatch returns a 3-part list that consists of the value of the function tried, warnings, and errors. It combines a solution presented by Martin Morgan and R’s internal help files. I found it to be incredibly useful and will be adding it to my personal R package (future post!). Here’s the output of the use case examples:

> myTryCatch(1+1) # legit
$value
[1] 2
$warning
NULL
$error
NULL
> myTryCatch(log(-1)) # NaN + warning
$value
[1] NaN
$warning
<simpleWarning in log(-1): NaNs produced>
$error
NULL
> myTryCatch(“a”+1) # error
$value
NULL
$warning
NULL
$error
<simpleError in “a” + 1: non-numeric argument to binary operator>