如何检查函数调用是否会导致警告?

Ale*_*mbe 55 r

在R中,如何确定函数调用是否会导致警告?

也就是说,在调用函数之后,我想知道该调用的实例是否产生了警告.

Jor*_*eys 65

如果要使用try构造,可以设置警告选项.另见?options.更好的是使用tryCatch():

x <- function(i){
  if (i < 10) warning("A warning")
  i
}

tt <- tryCatch(x(5),error=function(e) e, warning=function(w) w)

tt2 <- tryCatch(x(15),error=function(e) e, warning=function(w) w)

tt
## <simpleWarning in x(5): A warning>

tt2
## [1] 15

if(is(tt,"warning")) print("KOOKOO")
## [1] "KOOKOO"

if(is(tt2,"warning")) print("KOOKOO")
Run Code Online (Sandbox Code Playgroud)

要获得结果和警告:

tryCatch(x(5),warning=function(w) return(list(x(5),w)))

## [[1]]
## [1] 5
## 
## [[2]]
## <simpleWarning in x(5): A warning>
Run Code Online (Sandbox Code Playgroud)

运用 try

op <- options(warn=2)

tt <- try(x())
ifelse(is(tt,"try-error"),"There was a warning or an error","OK")
options(op)
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的编辑,显示如何获得结果和警告; 但是,当有警告时,该函数会被调用两次.它只能通过一次调用完成(例如,如果函数很慢)? (5认同)

Aar*_*ica 24

在R-help邮件列表中(见http://tolstoy.newcastle.edu.au/R/help/04/06/0217.html),Luke Tierney写道:

"如果你想编写一个计算值并收集所有警告的函数,你可以这样做:

withWarnings <- function(expr) {
    myWarnings <- NULL
    wHandler <- function(w) {
        myWarnings <<- c(myWarnings, list(w))
        invokeRestart("muffleWarning")
    }
    val <- withCallingHandlers(expr, warning = wHandler)
    list(value = val, warnings = myWarnings)
} 
Run Code Online (Sandbox Code Playgroud)

  • 是的,这样它会更新函数外的`myWarnings`; 否则它会在函数内部生成一个新的`myWarnings`,而外部函数则不会更新. (4认同)
  • 这是一个非常出色的解决方案,我不断地回顾。 (2认同)

koh*_*ske 6

这是一个例子:

testit <- function() warning("testit") # function that generates warning.

assign("last.warning", NULL, envir = baseenv()) # clear the previous warning

testit() # run it

if(length(warnings())>0){ # or !is.null(warnings())
    print("something happened")
}
Run Code Online (Sandbox Code Playgroud)

也许这是间接的,但我不知道更直接的方式.


Tom*_*ood 5

2019年更新

您可以使用 purrr 包中的 'quietly',它返回输出、结果、警告和错误的列表。然后,您可以按名称提取每个元素。例如,如果你有一个列表,你想映射一个函数,并找到返回警告的元素,你可以这样做

library(purrr)
library(lubridate)

datelist <- list(a = "12/12/2002", b = "12-12-2003", c = "24-03-2005")

# get all the everything
quiet_list <- map(datelist, quietly(mdy))

# find the elements which produced warnings
quiet_list %>% map("warnings") %>% keep(~ !is.null(.))

# or 
quiet_list %>% keep(~ length(.$warnings) != 0)
Run Code Online (Sandbox Code Playgroud)

对于此示例,它非常简单,但是对于可能难以发现 NA 的一长串数据帧列表,这非常有用。