Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Debugging unexpected errors in R -- how can I find where the error occurred?

Sometimes R throws me errors such as

Error in if (ncol(x) != 2) { : argument is of length zero

with no additional information, when I've written no such code. Is there a general way for finding which function in which package causes an error?

Since most packages come compressed, it isn't trivial to grep /usr/lib/R/library.

like image 940
Tim Avatar asked Nov 19 '12 14:11

Tim


People also ask

How do I trace back an error in R?

The traceback() function prints the list of functions that were called before the error occurred. The functions are printed in reverse order. traceback() does not tell you where in the function the error occurred. In order to know which line causes the error, you may want to step through the function using debug().

How do I debug an error in RStudio?

If you're diagnosing a specific error, you can have RStudio halt execution at the point where the error is raised. To do this, go to Debug -> On Error and change the value from “Error Inspector” to “Break in Code”.

How do I stop debug in R?

Q to stop debug mode, terminate the function, and return to the R prompt.

How is debugging done in R?

In R, debug () function allows the user to step through the execution of a function. At any point, we can print the values of the variables or draw a graph of the results within the function. While debugging, we can just type "c" to continue to the end of the current block of code.


2 Answers

You can use traceback() to locate where the last error occurred. Usually it will point you to a call you make in your function. Then I typically put browser() at that point, run the function again and see what is going wrong.

For example, here are two functions:

f2 <- function(x)
{
  if (x==1) "foo"
}

f <- function(x)
{
  f2(x)
}

Note that f2() assumes an argument of length 1. We can misuse f:

> f(NULL)
Error in if (x == 1) "foo" : argument is of length zero

Now we can use traceback() to locate what went wrong:

> traceback()
2: f2(x) at #3
1: f(NULL)

The number means how deep we are in the nested functions. So we see that f calls f2 and that gives an error at line 3. Pretty clear. We could reassign f with browser placed just before the f2 call now to check it's input. browser() simply allows you to stop executing a function and look around in its environment. Similar to debug and debugonce except that you don't have to execute every line up until the point you know something goes wrong.

like image 67
Sacha Epskamp Avatar answered Sep 30 '22 13:09

Sacha Epskamp


Just to add to what @SachaEpskamp has already suggested, setting options(error=recover) and options(show.error.locations=TRUE) can be extremely helpful when debugging unfamiliar code. The first causes R to launch a debugging session on error, giving you the option to invoke the browser at any point in the call stack up to that error. The second option will tell R to include the source line number in the error.

like image 36
Matthew Plourde Avatar answered Sep 30 '22 14:09

Matthew Plourde