2013-05-11 78 views
2

在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文件。我认为这是字节编译的东西。

回答

2

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

一个例子(系基于?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有很多有用的调试工具,其中大部分是在答案从几年前讨论to this SO question

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)

+0

你可以详细说明一下,或者举个例子吗?这对初学者来说非常密集。 – Szabolcs 2013-05-11 02:14:46