Search code examples
rrstan

How to detect warnings in R and have a while loop run on a function as along as warnings are outputted?


I am currently running functions such as stan_glm and stan_glmer from the rstan package in R. I am calling each function 1000 times, and it turns out that about 75% of these runs result in an warning such as:

Warning messages:
1: There were 184 divergent transitions after warmup. Increasing adapt_delta above 0.95 may help. See
http://mc-stan.org/misc/warnings.html#divergent-transitions-after-warmup 
2: There were 1 chains where the estimated Bayesian Fraction of Missing Information was low. See
http://mc-stan.org/misc/warnings.html#bfmi-low 
3: Examine the pairs() plot to diagnose sampling problems
4: Markov chains did not converge! Do not analyze results! 

I would like to create a while loop that re-runs the function until I come across a run without an warning. Is there a way to flag or detect such warning messages as the one above? Thanks.


Solution

  • You can use tryCatch() function to catch errors and warnings and adjust your workflow based on the result, i.e:

    x = -3.5
    
    repeat{
    
      x <- x + 0.6
      print( paste("Current value of x is", x) )
    
      result <- tryCatch( log( x ), 
                          error = function(e) e, 
                          warning = function(w) w ) 
    
      if (inherits(result,"warning")) next  # For warnings - continue the next iteration
      if (inherits(result,"error")) stop( result )  # For errors - stop
    
    
      print( paste0(" log(",x,")=", result))
      break 
    }
    
    # [1] "Current value of x is -2.9"
    # [1] "Current value of x is -2.3"
    # [1] "Current value of x is -1.7"
    # [1] "Current value of x is -1.1"
    # [1] "Current value of x is -0.5"
    # [1] "Current value of x is 0.1"
    # [1] " log(0.1)=-2.30258509299404"
    

    However, be very careful with repeat and while loops as you might end up creating an infinite loop. It might be a good idea to check how many iterations the loop has executed and abort it in case there have been too many iterations:

    x = -3.5
    iter <- 0
    
    while (iter < 100) {
    
      x <- x + 0.6
      iter <- iter + 1
    
      print( paste("Current value of x is", x) )
    
      result <- tryCatch( log( x ), 
                          error = function(e) e, 
                          warning = function(w) w ) 
    
      if (inherits(result,"warning")) next  # For warnings - continue the next iteration
      if (inherits(result,"error")) stop( result )  # For errors - stop
    
    
      print( paste0(" log(",x,")=", result))
      break 
    }