[R] TryCatch() with read.csv("http://...")

Seth Falcon sfalcon at fhcrc.org
Wed Nov 23 19:00:43 CET 2005


Hi David,

On 23 Nov 2005, dlvanbrunt at gmail.com wrote:
> Since the read is inside a "FOR" loop, (pulling in and analyzing
> different data each time) I've been trying to use TryCatch() to pull
> in the file if it's OK, but to jump out to the next iteration of the
> loop otherwise (using "next"). 

I think this is a common approach.  Here's an example using try (not
tryCatch):

doRead <- function() {
    x <- runif(1)
    if (x < 0.2)
      stop("failure in doRead")
    x
}

iters <- 20
vals <- NULL
for (i in seq(length=iters)) {
    val <- try(doRead(), silent=TRUE)
    if (inherits(val, "try-error"))
      next
    else
      vals <- c(vals, val)
}


length(vals)
[1] 16   ## there were 4 errors


> This seems like it should be obvious, but I've read through the ?
> files and tried everything my smooth little brain can come up
> with... no luck. I still end up jumping out of the entire script if
> I hit an error page.

tryCatch and the associated tools are many things (very powerful, very
cool), but I think they are not obvious :-)

I'm not sure if you can use tryCatch directly... probably so, but it
isn't obvious to me ;-)  However, here is an example using
withCallingHandlers and withRestarts.

vals <- NULL
iters <- 20
withCallingHandlers({
    for (i in seq(length=iters)) {
        val <- withRestarts(doRead(),
                            skipError=function() return(NULL))
        if (!is.null(val))
          vals <- c(vals, val)
    }},
                    error=function(e) invokeRestart("skipError"))


What's happening here as I understand it:

1. Establish a restart with

      val <- withRestarts(doRead(),
                          skipError=function() return(NULL))

   This says, "mark this spot with a recovery function called
   'skipError'".  This code does not handle the error.  But marks a
   spot where recovery occur.

2. Establish a handler for errors.  This is the withCallingHandlers
   call.  When an error occurs the function specified by the error arg
   gets called.  In this case, we invoke the restart function created
   above.  The restart function is evaluated "in the right place".

Why this is good: it decouples the handling of errors from the
recovery from errors.  With try(), you have to catch and handle the
error all at once.  With the withCallingHandlers/withRestarts
approach, you can use the same inner code (the same restarts) and
build wrappers that do different things.

HTH,

+ seth


PS: I found the following chapter to be helpful:
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html




More information about the R-help mailing list