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

前端 未结 4 978
情话喂你
情话喂你 2020-11-29 23:00

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 yi

相关标签:
4条回答
  • 2020-11-29 23:22

    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)
    } 
    
    0 讨论(0)
  • 2020-11-29 23:27

    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.

    0 讨论(0)
  • 2020-11-29 23:35

    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.

    0 讨论(0)
  • 2020-11-29 23:39

    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)
    
    0 讨论(0)
提交回复
热议问题