Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging lapply/sapply calls

Tags:

r

Use the standard R debugging techniques to stop exactly when the error occurs:

options(error = browser) 

or

options(error = recover)

When done, revert to standard behaviour:

options(error = NULL)

If you wrap your inner function with a try() statement, you get more information:

> sapply(x, function(x) try(1/x))
Error in 1/x : non-numeric argument to binary operator
[1] "-0.5"                                                    
[2] "Error in 1/x : non-numeric argument to binary operator\n"
[3] "Inf"                                                     
[4] "1"                                                       
[5] "0.5"

In this case, you can see which index fails.


Use the plyr package, with .inform = TRUE:

library(plyr)
laply(x, function(x) 1/x, .inform = TRUE)

Like geoffjentry said:

> sapply(x, function(x) {
  res <- tryCatch(1 / x,
                  error=function(e) {
                          cat("Failed on x = ", x, "\n", sep="") ## browser()
                          stop(e)
                        })
})

Also, your for loop could be rewritten to be much cleaner (possibly a little slower):

> y <- NULL
> for (xi in x)
    y <- c(y, 1 / xi)

Error in 1/xi : non-numeric argument to binary operator

For loops are slow in R, but unless you really need the speed I'd go with a simple iterative approach over a confusing list comprehension.

If I need to figure out some code on the fly, I'll always go:

sapply(x, function(x) {
  browser()
  ...
})

And write the code from inside the function so I see what I'm getting.

-- Dan


Using debug or browser isn't a good idea in this case, because it will stop your code so frequently. Use Try or TryCatch instead, and deal with the situation when it arises.