2013-05-11 82 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