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

mat*_*fee 11 r

我有一个围绕warning()R中内置函数的包装器,基本上调用warning(sprintf(...)):

warningf <- function(...)
    warning(sprintf(...))
Run Code Online (Sandbox Code Playgroud)

这是因为我warning(sprintf(...))经常使用,所以我决定用它来创建一个函数(它在我经常使用的函数的包中).

然后warningf我在写函数时使用.即,而不是写:

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

我写:

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

如果我打电话给第一个f(),我得到:

Warning message:
In f() : I have 2 bananas!
Run Code Online (Sandbox Code Playgroud)

这很好 - 它告诉我警告来自哪里f()以及出了什么问题.

如果我打电话给第二个f(),我得到:

Warning message:
In warningf("I have %i bananas!",2) : I have 2 bananas!
Run Code Online (Sandbox Code Playgroud)

这不是理想的 - 它告诉我警告是在warningf函数中(当然,因为它warningf是调用的函数warning,而不是f),掩盖它实际上来自f()函数的事实.

所以我的问题是:我可以以某种方式"提升" warning呼叫,以便显示warning in f()消息而不是warning in warningf

And*_*rie 14

解决此问题的一种方法是获取调用堆栈中的环境列表,然后在警告中粘贴父框架的名称.

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

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

现在,如果我运行你的功能:

> f()
Warning message:
In f() : I have 2 bananas! 
Run Code Online (Sandbox Code Playgroud)