views:

176

answers:

2

How do I write R code that allows me to execute a different path in my code if an error condition happens? I'm using a function that tends to throw an error. When it meets an error condition I would like to execute a different function. Here's a specific example:

require(SuppDists)
parms <- structure(list(gamma = -0.841109044800762, delta = 0.768672140584442, 
    xi = -0.359199299528801, lambda = 0.522761187947026, type = "SB"), .Names = c("gamma", 
"delta", "xi", "lambda", "type"))
pJohnson(.18, parms)

the pJohnson function should fail with the following error:

 Error in pJohnson(0.18, parms) :
 Sb values out of range.

I can make the error go silent by using:

try( pJohnson(.18, parms), silent=T)

but what I really want to do is execute the function alternativeFunction() if pJohnson(.18, parms) returns an error.

It seems like the withCallingHandlers() function should help me out, but I can't figure out how to capture the error and make it run the alternativeFunction() only upon an error condition.

Thanks for your help.

+8  A: 
t <- try(pJohnson(.18, parms))
if("try-error" %in% class(t)) alternativeFunction()
Ian Fellows
clearly a case of me not thinking "objecty" enough. thank you for the fast response!
JD Long
`if (inherits(t, "try-error")) alternativeFunction()` is a nice alternative that is even more 'objecty' than the `%in%`.
Dirk Eddelbuettel
Good point. The object abstraction layer for s3 classes is so transparent, I almost forget that it is there.
Ian Fellows
+2  A: 

Another option might be to use a tryCatch expression. Here's an example:

 vari <- 1
 tryCatch(print("passes"),  error = function(e) print(vari)) # => passes
 tryCatch(stop("fails"),  error = function(e) print(vari)) # => 1

You can do whatever you want within the error block, so in your case, something like this should work:

tryCatch(pJohnson(.18, parms), error=function(e) alternativeFunction())

This isn't really the intended usage of the error, but it's a little more concise.

Shane
hey that's pretty handy. Thanks!
JD Long