3

In R, if execution stops because of an error, I can evaluate traceback() to see which function the error occurred in, which function was that function called from, etc. It'll give something like this:

8: ar.yw.default(x, aic = aic, order.max = order.max, na.action = na.action, 
       series = series, ...)
7: ar.yw(x, aic = aic, order.max = order.max, na.action = na.action, 
       series = series, ...)
6: ar(x[, i], aic = TRUE)
5: spectrum0.ar(x)
4: effectiveSize(x)

Is there a way to find what arguments were passed to these functions? In this case, I'd like to know what arguments were passed to effectiveSize(), i.e. what is x.

The error does not occur in my own code, but in a package function. Being new to R, I'm a bit lost.

Not knowing how to do this properly, I tried to find the package function's definition and modify it, but where the source file should be I only find an .rdb file. I assume this is something byte-compiled.

Szabolcs
  • 24,728
  • 9
  • 85
  • 174

2 Answers2

3

I'd suggest setting options(error=recover) and then running the offending code again. This time, when an error is encountered, you'll be thrown into an interactive debugging environment in which you are offered a choice of frames to investigate. It will look much like what traceback() gives you, except that you can type 7 to enter the evaluation environment of call 7 on the call stack. Typing ls() once you've entered a frame will give you the list of its arguments.

An example (based on that in ?traceback) is probably the best way to show this:

foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }

## First with traceback()
foo(2) # gives a strange error
# [1] 1
# Error in bar(2) : object 'a.variable.which.does.not.exist' not found
traceback()
# 2: bar(2) at #1
# 1: foo(2)

## Then with options(error=recover)
options(error=recover)
foo(2) 
# [1] 1
# Error in bar(2) : object 'a.variable.which.does.not.exist' not found
# 
# Enter a frame number, or 0 to exit   
# 
# 1: foo(2)
# 2: #1: bar(2)

Selection: 1
# Called from: top level 
Browse[1]> ls()
# [1] "x"
Browse[1]> x
# [1] 2
Browse[1]>    ## Just press return here to go back to the numbered list of envts.
# 
# Enter a frame number, or 0 to exit   
# 
# 1: foo(2)
# 2: #1: bar(2)

R has many helpful debugging tools, most of which are discussed in the answers to this SO question from a few years back.

Community
  • 1
  • 1
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
2

You can use trace() to tag or label a function as requiring a "detour" to another function, the logical choice being browser().

 ?trace
 ?browser

> trace(mean)
> mean(1:4)
trace: mean(1:4)
[1] 2.5

So that just displayed the call. This next mini-session shows trace actually detouring into the browser:

> trace(mean, browser)
Tracing function "mean" in package "base"
[1] "mean"
> mean(1:4)
Tracing mean(1:4) on entry 
Called from: eval(expr, envir, enclos)
Browse[1]> x      #once in the browser you can see what values are there
[1] 1 2 3 4
Browse[1]> 
[1] 2.5
> untrace(mean)
Untracing function "mean" in package "base"

As far as seeing what is in a function, if it is exported, you can simply type its name at the console. If it is not exported then use: getAnywhere(fn_name)

IRTFM
  • 258,963
  • 21
  • 364
  • 487