2010-10-26 65 views
8
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

下面是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

您可能也喜欢返回警告的数量作为答案的属性。 'attr(ans,“number_of_warnings”)< - .number_of_warnings' – 2010-10-26 10:49:15

+0

太好了!我也可以用这种方式抓住警告信息('w') – 2010-10-27 04:42:40

+1

不客气。没有什么表示感谢你喜欢upvote。 :) – 2010-10-27 07:45:21

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被置位,直到调用完成(特别是考虑到该呼叫是可以返回哪一部分)。

+0

感谢,因为你在我的地方吐出 “的警告数:0” 看它不工作的我的机器OSX R 2.11.1 GUI 1.34 Leopard构建32位(5589)。嗯现在我应该尝试什么? – 2010-10-26 02:38:56

+0

看我的编辑(我忘了清除'last.warning')。我不认为这是针对特定平台的。 – 2010-10-26 02:41:47

+0

如果你认为'last.warning'没有被设置,直到返回,然后我卡住了。在函数中,如何确定是否发生警告,而不会丢失函数要返回的值?使用'tryCatch'当然会捕获警告,但是如果没有嵌入'tryCatch',函数将会返回该值的值。 – 2010-10-26 02:56:44

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() 

调用该函数两次,如果出现警告...... 虽然我相信一定有更优雅的解决方案

+0

是的,我刚开始考虑这个:)我的代码和代码都很痛苦 – 2010-10-26 06:51:19

0

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

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

就像第一个回答的人,我想你可能忘记调用assign(“last.warning”,NULL,envir = baseenv ())。如果是这样,该函数发现的1个警告来自先前的呼叫。 – 2010-10-26 08:35:11

+0

哦,该死的,没错。在那里发生一些可疑的事情。 – VitoshKa 2010-10-26 09:31:53

+0

这看起来像是一个bug。我会在r-devel上报告它。 – VitoshKa 2010-10-26 09:42:00

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 
> 
+0

是的,但是,说实话,我用'<< - '很多:) – 2010-10-26 09:50:40

+1

另一种方法是使用选项。在任何情况下,某种 “全球性”是需要的。 – VitoshKa 2010-10-26 10:01:51