0

I have some loop that computes a value. Sometimes that computation triggers a warning. How do I check if the warning is triggered, then skip that iteration? I am using R.

With help from the comments, I found tryCatch() and was able to amend my for loop as the following and work:

for (i in seq(1,100,1)){
    x<-sample(1:length(df$values), 1)
    input<-copy_df[x:x+5,]
    val<-tryCatch(myfunc(input$colA), warning=function(w) w)
    if (is(val,warning){ 
        next
    }
    print(paste0(i))
}

The output of val should be a column of length 5.

Jack Armstrong
  • 1,182
  • 4
  • 26
  • 59
  • See the `?Control` help page. The for loop has a `next` keyword to move to the next iteration. But in general it's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Jan 21 '21 at 16:59
  • See also the other duplicate for how to check for a warning: https://stackoverflow.com/questions/3903157/how-can-i-check-whether-a-function-call-results-in-a-warning – MrFlick Jan 21 '21 at 17:01
  • it is difficult to detect where the warning occurs because I am passing a random observation through each time I iterate over my loop. Therefore, it is difficult to debug and create a reproducible example. The functionality I am asking for is not related to myfunc(), but more handle warnings(). – Jack Armstrong Jan 21 '21 at 17:02
  • Just wrap the `tryCatch` around anything that might generate the warning. – MrFlick Jan 21 '21 at 17:03

1 Answers1

1

Here's a complete example using a test function that randomly generates a warning

set.seed(101)
foo <- function() {
  x <- runif(1)
  if(x<.9) warning("low x")
  x
}
for(i in 1:20) {
  didwarn <- tryCatch({x <- foo(); FALSE}, warning = function(w) return(TRUE))
  if(didwarn) {
    next
  }
  print(paste("high x", x))
}

You wrap any code that might trigger a warning in a try catch. Here we have each block return TRUE or FALSE depending on whether or not an error was thrown. An easier way to do this without the next would be

for(i in 1:20) {
  tryCatch({
      x <- foo(); 
      print(paste("high x", x))
    }, 
    warning = function(w) {
      # do nothing
    })
}

When the warning occurs, nothing else in the tryCatch expression will run

MrFlick
  • 195,160
  • 17
  • 277
  • 295