How can I check whether a function call results in a warning?

R

R Problem Overview


In R, how can I determine whether a function call results in a warning?

That is, after calling the function I would like to know whether that instance of the call yielded a warning.

R Solutions


Solution 1 - R

If you want to use the try constructs, you can set the options for warn. See also ?options. Better is to use 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")

To get both the result and the warning :

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

## [[1]]
## [1] 5
## 
## [[2]]
## <simpleWarning in x(5): A warning>

Using try

op <- options(warn=2)

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

Solution 2 - R

On the R-help mailing list (see http://tolstoy.newcastle.edu.au/R/help/04/06/0217.html), Luke Tierney wrote:

"If you want to write a function that computes a value and collects all warning you could do it like this:

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

Solution 3 - R

here is an example:

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")
}

maybe this is somehow indirect, but i don't know the more straightforward way.

Solution 4 - R

2019 update

You can you use 'quietly' from the purrr package, which returns a list of output, result, warning and error. You can then extract each element by name. For instance, if you had a list, which you want to map a function over, and find the elements which returned a warning you could do

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)

For this example it's quite trivial, but for a long list of dataframes where the NAs might be hard to spot, this is quite useful.

Solution 5 - R

For a simple TRUE/FALSE return on whether a given operation results in a warning (or error), you could use the is.error function from the berryFunctions package, after first setting options(warn = 2) so that warnings are converted to errors.

E.g.,

options(warn = 2)
berryFunctions::is.error(as.numeric("x")) # TRUE
berryFunctions::is.error(as.numeric("3")) # FALSE

If you want to limit the option change to the use of this function, you could just create a new function as follows.

is.warningorerror <- function(x) {
 op <- options()
 on.exit(options(op))
 options(warn = 2)
 berryFunctions::is.error(x)
}

is.warningorerror(as.numeric("x")) # TRUE
options("warn") # still 0 (default)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex HolcombeView Question on Stackoverflow
Solution 1 - RJoris MeysView Answer on Stackoverflow
Solution 2 - RAaron left Stack OverflowView Answer on Stackoverflow
Solution 3 - RkohskeView Answer on Stackoverflow
Solution 4 - RTom GreenwoodView Answer on Stackoverflow
Solution 5 - RThomas FarrarView Answer on Stackoverflow