Let's say I have just called a function, f
, and an error occurred somewhere in the function. I just want to be able to check out the values of different variables right before the error occurred.
Suppose my gut tells me it's a small bug, so I'm too lazy to use debug(f)
and too lazy to insert browser()
into the part of the function where I think things are going wrong. And I'm far too lazy to start putting in print()
statements.
Here's an example:
x <- 1:5
y <- x + rnorm(length(x),0,1)
f <- function(x,y) {
y <- c(y,1)
lm(y~x)
}
Calling f(x,y)
we get the following error:
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
In this example, I want grab the state of the environment just before lm()
is called; that way I can call x
and y
and see that their lengths are different. (This example may be too simple, but I hope it gets the idea across.)
Use traceback() to determine where a given error is occurring. Output diagnostic information in code with print() , cat() or message() statements. Use debug() to automatically open a debugger at the start of a function call. Use trace() to start a debugger at a location inside a function.
The error means that R could not find the variable mentioned in the error message. The easiest way to reproduce the error is to type the name of a variable that doesn't exist. (If you've defined x already, use a different variable name.)
A variable in R can be defined using just letters or an underscore with letters, dots along with letters. We can even define variables as a mixture of digits, dot, underscore and letters.
Use the assignment operator <- to create new variables. A wide array of operators and functions are available here. (To practice working with variables in R, try the first chapter of this free interactive course.)
As pointed out here, there's an easy way to do this, and I think this trick has the potential to change lives for the better.
First, call this:
options(error=recover)
Now when we call f(x,y)
we will have an option to choose an environment to recover. Here I select option 1, which opens up a debugger and lets me play around with variables just before lm()
is called.
> f(x,y)
Error in model.frame.default(formula = y ~ x, drop.unused.levels = TRUE) :
variable lengths differ (found for 'x')
Enter a frame number, or 0 to exit
1: f(x, y)
2: lm(y ~ x)
3: eval(mf, parent.frame())
4: eval(expr, envir, enclos)
5: model.frame(formula = y ~ x, drop.unused.levels = TRUE)
6: model.frame.default(formula = y ~ x, drop.unused.levels = TRUE)
Selection: 1
Called from: eval(expr, envir, enclos)
Browse[1]> x
[1] 1 2 3 4 5
Browse[1]> y
[1] 1.6591197 0.5939368 4.3371049 4.4754027 5.9862130 1.0000000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With