warnings()在函数内不起作用?如何解决这个问题?

时间:2010-10-26 02:25:11

标签: r error-handling

op <- options(warn=0)  #although doesn't work for any value of warn
assign("last.warning", NULL, envir = baseenv())  
thisDoesntWork<- function() {
warning("HEY, this is definitely a warning!")
cat(paste("number of warnings:",length(warnings())))
}   
>thisDoesntWork()
Warning in thisDoesntWork() : HEY, this is definitely a warning!
number of warnings: 0

警告数量应为1而不是0 - 似乎warnings()在函数内调用时不返回任何内容。为什么?如果发生警告,如何解决这个问题以解决这个问题并将其打印出来?

我不想使用tryCatch,因为我失去了函数返回的值(它可能仍然返回一个有效值,即使它产生了警告)。

5 个答案:

答案 0 :(得分:5)

以下是suppressWarnings

的代码
function (expr) 
{
    withCallingHandlers(expr, warning = function(w) invokeRestart("muffleWarning"))
}

我已经稍微调整一下来计算警告的次数。

countWarnings <- function(expr) 
{
    .number_of_warnings <- 0L
    frame_number <- sys.nframe()
    ans <- withCallingHandlers(expr, warning = function(w) 
    {
      assign(".number_of_warnings", .number_of_warnings + 1L, 
        envir = sys.frame(frame_number))
      invokeRestart("muffleWarning")
    })
    message(paste("No. of warnings thrown:", .number_of_warnings))
    ans
}

测试:

countWarnings(log(-1))
No. of warnings thrown: 1
[1] NaN

另一项测试:

foo <- function()
{
  warning("first warning!")
  warning("second warning!")
  warning("third warning!")
  invisible()
}
countWarnings(foo())
No. of warnings thrown: 3
NULL

答案 1 :(得分:2)

您的示例 会返回警告。

> assign("last.warning", NULL, envir = baseenv())  
> thisDoesntWork <- function() {
+   warning("HEY, this is definitely a warning!")
+   cat(paste("number of warnings:",length(warnings())),"\n")
+ }
> thisDoesntWork()
number of warnings: 0 
Warning message:
In thisDoesntWork() : HEY, this is definitely a warning!
> warnings()  # HEY, here's your warning!!!
Warning message:
In thisDoesntWork() : HEY, this is definitely a warning!

文档不明确,但我认为last.warning在调用完成之前不会被设置(特别是考虑到调用是可以返回的内容的一部分)。

答案 2 :(得分:2)

可能这是一个非常糟糕的解决方法......

fw<-function(){warning("warn...");return(99)}
fn<-function(){return(88)}

f<-function(){
    w<-0
    v<-NULL
    v<-tryCatch(fw(),warning=function(w){w})
    if("warning"%in%class(v)){
        w<-w+1 # e.g., count up the number of warning
        v<-fw()
    }
    print(v)

    v<-NULL
    v<-tryCatch(fn(),warning=function(w){w})
    if("warning"%in%class(v)){
        w<-w+1 # e.g., count up the number of warning
        v<-fn()
    }
    print(v)
}
f()
如果发生警告,

调用该函数两次... 虽然我相信必须有更优雅的解决方案

答案 3 :(得分:1)

这是一种解决方法

..my_warning <- 0L

thisDoesWork<- function(){
    assign("last.warning", NULL, envir = baseenv())  
    warning("HEY, this is definitely a warning!", {..my_warning <<- ..my_warning+1L;""})
    str(last.warning)
    cat(paste("number of warnings:", ..my_warning, "\n"))
}


thisDoesWork()
Warning in thisDoesWork() : HEY, this is definitely a warning!
NULL
number of warnings: 1 
>     thisDoesWork()
Warning in thisDoesWork() : HEY, this is definitely a warning!
NULL
number of warnings: 2 
>     thisDoesWork()
Warning in thisDoesWork() : HEY, this is definitely a warning!
NULL
number of warnings: 3 
> 

答案 4 :(得分:0)

警告不是在函数返回之前发出的。 请参阅选项文档(“警告”):

options(warn=1L)
thisDoesntWork()
#Warning in thisDoesntWork() : HEY, this is definitely a warning!
#number of warnings: 1