3

在 R 中,如果由于错误而停止执行,我可以评估traceback()以查看错误发生在哪个函数中,该函数是从哪个函数调用的,等等。它会给出如下内容:

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)

有没有办法找到传递给这些函数的参数?在这种情况下,我想知道传递给 的参数是effectiveSize()什么,即是什么x

该错误不会出现在我自己的代码中,而是出现在一个包函数中。作为 R 的新手,我有点迷茫。

不知道如何正确执行此操作,我试图找到包函数的定义并对其进行修改,但是源文件应该在哪里,我只找到了一个.rdb文件。我认为这是字节编译的。

4

2 回答 2

3

我建议设置options(error=recover)然后再次运行有问题的代码。这一次,当遇到错误时,您将进入一个交互式调试环境,您可以在其中选择要调查的帧。它看起来很像traceback()给你的东西,除了你可以在调用堆栈上键入7进入调用的评估环境。一旦你输入了一个框架,输入就会给你它的参数列表7ls()

一个示例(基于 中的示例?traceback)可能是展示这一点的最佳方式:

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 有许多有用的调试工具,其中大部分在几年前对这个 SO 问题的答案中进行了讨论。

于 2013-05-11T02:25:04.043 回答
2

您可以使用trace()标记或标记一个功能需要“绕道”到另一个功能,逻辑选择是browser().

 ?trace
 ?browser

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

所以这只是显示呼叫。下一个迷你会话显示实际上绕道进入浏览器的跟踪:

> 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"

至于查看函数中的内容,如果它被导出,您只需在控制台中键入它的名称即可。如果未导出,则使用:getAnywhere(fn_name)

于 2013-05-11T01:48:42.143 回答