2

I am running a glm() function nested in for() function. The output of the glm is entered into a matrix. For some of the cycles there is a warning but i get all the warnings only at the end of all the cycles so i can not know which cycle was bad. I would like to get an indication if there is a warning after each glm calculation so i can tell the script not to enter this cycle result to the matrix. Any ideas how to do this? example:

   m<-matrix(nc=1,nr=100)
   for(i in 1:100){      
   fit<-glm(y~x+v1+v2+v3,data=data)
   if("there is a warning???"){
   m[i,1]<-NA
   }
   else{
   m[i,1]<-fit$coefficients[2,1]
   }
    "reset warning???"
    }

Thank you

hans
  • 91
  • 1
  • 7
  • 2
    http://stackoverflow.com/questions/3903157/how-can-i-check-whether-a-function-call-results-in-a-warning – eddi Apr 08 '13 at 19:51
  • When I need to do this I store the result and all warnings and errors in a list and then process the warnings afterwards, as described here: http://stackoverflow.com/q/4948361/210673 – Aaron left Stack Overflow Apr 08 '13 at 21:02

2 Answers2

2

Here's a function that sometimes warns but always returns a value

f <- function() {
    r <- runif(1)
    if (r > 1) warning("high")
    Sys.sleep(.1)  # 'expensive' calculation after warning
    r
}

The following loop is meant to update x[i] with the value returned by f(). Caught warnings are replaced by NA; the part of f after the warning is not evaluated. We're not interested in processing the warning message so we ignore the argument provided to the warning handler.

x <- numeric(10)
for (i in seq_along(x)) {
    x[i] <- tryCatch(f(), warning=function(...) NA)
}

So for instance

> set.seed(123)
> system.time(x <- replicate(100, tryCatch(f(), warning=function(...) NA)))
   user  system elapsed 
  0.052   0.000   8.364 
> table(is.na(x))

FALSE  TRUE 
   83    17 

It's hard to reproduce your particular question, because data is not provided. I think you want to do

m <- matrix(ncol=1, nrow=100)
for(i in 1:100) {
    m[i,1] <- tryCatch({
        fit <- glm(y~x+v1+v2+v3, data=data)
        fit$coefficients[2, 1]
    }, warning=function(...) NA)
}
Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
  • thank you Martin, the tryCatch() is what i needed. The output of glm is a list and of warning in your example is NA. Therefore I filtered the desired output by asking is.list() as follows: – hans Apr 12 '13 at 19:12
  • `m<-matrix(nc=1,nr=100) for(i in 1:100){ fit<-tryCatch(glm(y~x+v1+v2+v3,data=data),warning=function(...) NA) if(is.list(fit)){ m[i,1]<-fit$coefficients[2,1] } }` – hans Apr 12 '13 at 19:20
  • @hans I tried to illustrate your case more directly in my answer. – Martin Morgan Apr 12 '13 at 20:21
1

Besides that fabulous link given in the comment above by eddi, you could try the combination of making warnings to errors and jump into the function at an error:

options(warn = 2) # will turn warnings into errors
options(error = recover) # will allow you to browser() at the error.

Depending on the size of your problem the option given in the link above could nevertheless be better. But my solution is fairly easy to implement.

Henrik
  • 14,202
  • 10
  • 68
  • 91