The most straightforward way is to wrap our problematic call in a tryblock:
> for(input in inputs) {
+ try(print(paste("log of", input, "=", log(input))))
+ }
[[1] "log of 1 = 0"
[1] "log of 2 = 0.693147180559945"
[1] "log of 4 = 1.38629436111989"
[1] "log of -5 = NaN"
Error in log(input) : Non-numeric argument to mathematical function
In addition: Warning message:
In log(input) : NaNs produced
[1] "log of 0 = -Inf"
[1] "log of 10 = 2.30258509299405"
This skips over the error-causing non-numeric input with an error message (you can suppress the error message with the silent=Targument to try), and continues on with the rest of the input. Generally, this is what you would like.
The tryCatch block
Sometimes, however, you might want substitute your own return value when errors (or warnings) are returned. We can do this with tryCatch, which allows you to write your own error and warning handlers. Let’s set our loop to return log(-x) when x is negative (negative arguments throw a warning) and return a NaN for non-numeric arguments (which throw an error). We’ll print out an advisory message, too.
> for(input in inputs) {
+ tryCatch(print(paste("log of", input, "=", log(input))),
+ warning = function(w) {print(paste("negative argument", input));
log(-input)},
+ error = function(e) {print(paste("non-numeric argument", input));
NaN})
+ }
[1] "log of 1 = 0"
[1] "log of 2 = 0.693147180559945"
[1] "log of 4 = 1.38629436111989"
[1] "negative argument -5"
[1] "non-numeric argument oops"
[1] "log of 0 = -Inf"
[1] "log of 10 = 2.30258509299405"