2012-03-07 14 views
10

我身邊有R中的內置warning()功能,基本上調用warning(sprintf(...))包裝:R警告()包裝 - 提高到父函數

warningf <- function(...) 
    warning(sprintf(...)) 

這是我用warning(sprintf(...))經常,我決定做一個功能(它在我有我經常使用的功能的軟件包中)。我寫函數時使用warningf。即,而不是寫:

f <- function() { 
    # ... do stuff 
    warning(sprintf('I have %i bananas!',2)) 
    # ... do stuff 
} 

我寫:

f <- function() { 
    # ... do stuff 
    warningf('I have %i bananas!',2) 
    # ... do stuff 
} 

如果我把第一f(),我得到:

Warning message: 
In f() : I have 2 bananas! 

這是一件好事 - 它告訴我哪裏有警告來自f(),出了什麼問題。

如果我稱第二f(),我得到:

Warning message: 
In warningf("I have %i bananas!",2) : I have 2 bananas! 

這不是理想的 - 它告訴我的警告是在warningf功能(當然,因爲它是warningf函數調用warning,不f),掩蓋了它實際上來自f()函數的事實。

所以我的問題是:我可以以某種方式「提高」warning呼叫,因此它顯示warning in f()消息,而不是warning in warningf

回答

12

處理此問題的一種方法是獲取調用堆棧中的環境列表,然後在警告中粘貼父框架的名稱。

您可以使用函數sys.call()來執行此操作,該函數返回調用堆棧中的項目。你想從這個列表中最後一個元素,即父第二解壓到warningf

warningf <- function(...){ 
    parent.call <- sys.call(sys.nframe() - 1L) 
    warning(paste("In", parent.call, ":", sprintf(...)), call.=FALSE) 
} 

現在,如果我跑你的函數:

> f() 
Warning message: 
In f() : I have 2 bananas! 
+0

@richiecotton感謝你的編輯。你的方式好多了。 – Andrie 2012-03-07 11:06:24

+0

+1 - 很好的答案。更簡單的是隻使用'sys.call(-1)'。 (它工作b/c'''sys.call()'''which'參數表示「如果負數返回的幀數」)。 – 2012-03-07 21:38:46

+0

太棒了!我認爲,當我查看「警告」代碼時,通過調用堆棧可能有些事情要做,但不知道如何去做。謝謝! – 2012-03-07 23:38:41