[R] How to catch both warnings and errors?

David Winsemius dwinsemius at comcast.net
Mon Dec 6 03:13:40 CET 2010


On Dec 5, 2010, at 7:35 PM, Marius Hofert wrote:

>
> On 2010-12-06, at 01:07 , David Winsemius wrote:
>
>>
>> On Dec 5, 2010, at 3:13 PM, Marius Hofert wrote:
>>
>>> Dear expeRts,
>>>
>>> I am struggling with warning/error handling.
>>>
>>> I would like to call a function which can produce either
>>> a) normal output
>>> b) a warning
>>> c) an error
>>>
>>> Since the function is called several (thousand) times in a loop, I  
>>> would like
>>> to proceed "quietly" and collect the warnings and errors [to deal  
>>> with them at a
>>> later point].
>>
>> I do not see the function warnings() being used below:
>>
>> ?warnings
>>
>> It delivers the stored warnings with different default behavior for  
>> interactive and non-interactive sessions.
>>>
>>> I have seen constructs with tryCatch (which can deal with errors)  
>>> and with
>>> withCallingHandlers (which can deal with warnings), but I cannot  
>>> figure out how
>>> to catch *both* warnings and errors. Below is a minimal example of  
>>> the function
>>> that is called several times in a large loop. The function should  
>>> catch warnings
>>> and errors; the former work fine, but with the latter I do not  
>>> know how to proceed.
>>>
>>
>>
>> Made some changes in you code but don't know if it is what you were  
>> hoping for:
>>
>> f <- function(x){
>>  ## warnings
>>  w.list <- NULL # init warning
>>  w.handler <- function(w){ # warning handler
>> 	    warn <- simpleWarning(w$message, w$call) # build warning
>> # first change here
>>      w.list <<- c(w.list, paste(warnings(), collapse = " ")) # save  
>> warning
>>      invokeRestart("muffleWarning")
>>      }
>>  ## errors
>>    e.list <- NULL # init errors   # not sure this is  good idea
>>    e.handler <- function(e){ # error handler
>> 	     err <- c(e.list, e$message, e$call) # save error
>> 	     return( err)
>>       }
>>  ## execute command
>> # wrapped cal in try()
>>  res <- withCallingHandlers(try(log(x)), warning = w.handler, error  
>> = e.handler)
>>  ## return result with warnings and errors
>>  list(result = res, warning = w.list, error = e.list)
>> }
>>
>
> Dear David,
>
> many thanks for your help.
> If I call your code with f(-1) and f("a"), I obtain:
>
>> f(-1)
> $result
> [1] NaN
>
> $warning
> [1] ""
>
> $error
> NULL



>
> => The problem is that the warning is not given.
>
>> f("a")
> Error in log(x) : Non-numeric argument to mathematical function
> $result
> [1] "Error in log(x) : Non-numeric argument to mathematical function 
> \n"
> attr(,"class")
> [1] "try-error"
>
> $warning
> NULL
>
> $error
> NULL
>
> => The problem is that the error message is printed to the R console  
> instead of suppressed (setting silent = TRUE didn't help either).  
> Further, the $error component is empty (the error message should  
> appear there -- if possible)

Sorry. I was being misled by warnings that existed at my global level  
into thinking i had succeeded. This modification will suppress warning  
and error but will not populate the lists as we had hoped:

f <- function(expr){
  ## warnings
  w.list <- NULL # init warning
  w.handler <- function(w){ # warning handler
	    warn <- c(w$message, w$call) # build warning
# first change here
      muffleWarning <<- c(w.list, warn, collapse = " ") # save warning
           invokeRestart("muffleWarning")}
  ## errors
    e.list <- NULL # init errors   # not sure this is  good idea
    e.handler <- function(e){ # error handler
	     e.list <<- c(e.list, e$message, e$call) # save error
	     return( e.list)
       }
  ## execute command
# wrapped cal in try()
  res <- withCallingHandlers(try(expr, silent=TRUE), warning =  
w.handler, error = e.handler)
  ## return result with warnings and errors
   list(result = res, warning = w.list, error = e.list)
}

 > test <- f(log(-1))
 > test
$result
[1] NaN

$warning
NULL

$error
NULL

 > test <- f(log("a"))
 > test
$result
[1] "Error in log(\"a\") : Non-numeric argument to mathematical  
function\n"
attr(,"class")
[1] "try-error"

$warning
NULL

$error
NULL



>
> Do you know a solution?

> Cheers,
>
> Marius
>

David Winsemius, MD
West Hartford, CT



More information about the R-help mailing list