2012-11-19 18 views
12

有時ř拋出我的錯誤,如如何找到R錯誤發生的地方?

錯誤如果(NcoI位(X)= 2!){:參數是長度爲零

與沒有附加信息,當我已經寫沒有這樣的代碼。是否有一種通用的方法來查找哪個包引起錯誤的函數?

由於大多數軟件包都是壓縮的,所以grep /usr/lib/R/library並不是微不足道的。

+0

我發現最簡單的調試方法是逐行執行代碼。如果你的錯誤來自你寫的函數,你可以使用'debugonce(function_name)'調試它。這將給你一個在功能範圍內的迷你R會話。 – Justin

+0

這就是我一直在做的事情,但我覺得我花費了太多時間在可以自動化的東西上。 – Tim

回答

17

您可以使用traceback()找到上次發生錯誤的位置。通常它會指向你在你的函數中進行的一個調用。然後,我通常會在此時放入browser(),再次運行該功能並查看發生了什麼問題。

例如,這裏有兩個功能:

f2 <- function(x) 
{ 
    if (x==1) "foo" 
} 

f <- function(x) 
{ 
    f2(x) 
} 

注意f2()假定長度1的參數。我們可以濫用f

> f(NULL) 
Error in if (x == 1) "foo" : argument is of length zero 

現在我們可以用traceback()找到什麼地方出了錯:

> traceback() 
2: f2(x) at #3 
1: f(NULL) 

數量意味着我們在嵌套函數有多深。所以我們看到f調用f2,並在行3處給出錯誤。很清楚。我們可以重新分配fbrowser,立即調用f2來檢查它的輸入。 browser()只是允許你停止執行一個功能,並環顧四周。類似於debugdebugonce,除非您不必執行每一行,直到出現錯誤。

+0

Nitpick:它不是'f2',假設參數的長度大於0,它就是'if'語句。 – naught101

16

只要添加到@SachaEpskamp已經建議的內容中,在調試不熟悉的代碼時,設置options(error=recover)options(show.error.locations=TRUE)會非常有幫助。第一種情況會導致R在發生錯誤時啓動調試會話,讓您可以選擇在調用堆棧中的任何位置調用瀏覽器,直至出現該錯誤。第二個選項將告訴R在錯誤中包含源代碼行號。

+2

另外,如果你設置了'options(warn = 2)',那麼在發出警告時也會發生同樣的情況,如果你最終導致錯誤地將數字轉換爲數字(誘發'NA',這通常不是你想要的 – richiemorrisroe

+0

因此,將選項設置爲選項(錯誤=恢復),選項(show.error.locations = TRUE)和選項(警告= 2),但希望將這些選項重置爲其原始狀態,我該怎麼做? – stochasticcrap

+1

'o < - options(error = recover,show.error.locations = TRUE,warn = 2);#do stuff; do.call(options,o)#reset'如果這個答案對你有幫助, –

相關問題