R warning()包装器-提升到父函数

R warning()包装器-提升到父函数,r,R,我在R中内置的warning()函数周围有一个包装器,它基本上调用warning(sprintf(…): 我写道: f <- function() { # ... do stuff warningf('I have %i bananas!',2) # ... do stuff } 这很好-它告诉我警告来自哪里以及哪里出了问题 如果调用第二个f(),我会得到: Warning message: In f() : I have 2 bananas! Warning

我在R中内置的
warning()
函数周围有一个包装器,它基本上调用
warning(sprintf(…)

我写道:

f <- function() {
    # ... do stuff
    warningf('I have %i bananas!',2)
    # ... do stuff
}
这很好-它告诉我警告来自哪里以及哪里出了问题

如果调用第二个
f()
,我会得到:

Warning message:
In f() : I have 2 bananas!
Warning message:
In warningf("I have %i bananas!",2) : I have 2 bananas!
这并不理想-它告诉我警告在
warningf
函数中(当然,因为调用
warningf
的是
warningf
函数,而不是
f
),掩盖了它实际上来自
f()
函数的事实


因此,我的问题是:我能否以某种方式“引发”这个
警告
调用,使它在f()中显示
警告
消息,而不是在warningf
中显示
警告?

处理这个问题的一种方法是获取调用堆栈中的环境列表,然后将父帧的名称粘贴到警告中

您可以使用函数
sys.call()
执行此操作,该函数返回调用堆栈中的一项。您想从列表中最后一个元素中提取第二个元素,即
警告f
的父元素:

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


稍后编辑:
deparse(parent.call)
如果
f()
函数有参数,则将调用转换为字符串,并按指定的方式显示调用(即包括参数等)。

我知道它很旧,但是,
sys.call(sys.nframe()-1L)
sys.call(-1)
, 返回带有函数名和参数的向量。 如果在
paste()
中使用它,它将引发两个警告,一个来自函数,一个来自参数。 答案不显示,因为
f()
没有参数。

sys.call(sys.nframe()-1L)[1]
成功了。

@richiecotton感谢您的编辑。你的方法好多了。+1--回答得好。更简单的方法是只使用
sys.call(-1)
。(它通过b/c
工作,该
参数指向
sys.call()
表示“如果为负,则返回的帧数”)。太棒了!当我看到
警告
代码时,我认为这可能与遍历调用堆栈有关,但不知道如何操作。谢谢这更多的是对原始答案的评论,而不是答案(同样,如果调用
f()
时没有原始问题中的参数,原始答案不会发出两个警告)。此外,建议的修复程序将只打印警告消息中的函数名,而不打印参数(即,不打印调用)。我已经更新了原始答案
deparse(parent.call)
目前是将调用转换为字符串的合适方法。很好:)我没有足够的声誉发表评论(奇怪的是,你可以回答但不能评论)。非常感谢。PS它不会发出两个警告,因为
f()
没有参数。如果您有一个带有参数的函数,
sys.call(sys.nframe()-1L)
将生成一个向量,并且对于每个therm,它将发出警告。
Warning message:
In warningf("I have %i bananas!",2) : I have 2 bananas!
warningf <- function(...){
  parent.call <- sys.call(sys.nframe() - 1L)
  warning(paste("In", deparse(parent.call), ":", sprintf(...)), call.=FALSE)
}  
> f()
Warning message:
In f() : I have 2 bananas!