Search code examples
rif-statementmetafor

Avoid warnings from FALSE part of ifelse()


I created a user function that computes Hedges' c() bias correction for g (Hedges, 1981). It is directly based on metafor::.cmicalc() function from library(metafor). It does this:

hedges_c <- function(df) {
  return(exp(lgamma(df / 2) - log(sqrt(df / 2)) - lgamma((df - 1)/2)))
}

When applied to a vector containing values <= 1, lgamma() generates a warning, because lgamma(0) (as well as any negative value) generates NaN. So, my solution (and also what metafor::.cmicalc() does) was including an ifelse() statement:

hedges_c <- function(df) {
  cdf <- ifelse(df <= 1, 
                NA,
                exp(lgamma(df / 2) - log(sqrt(df / 2)) - lgamma((df - 1)/2)))
  return(cdf)
}

But, and here is the problem I don't seem to find the solution to, it still generates the warnings(), even if all the values are correctly rendered as NA.

Example:

hedges_c(c(0, 0, 20, 14, 0, 0, 0, 0))
#[1]      NA      NA 0.9619445 0.9452877      NA      NA      NA      NA
#Warning messages:
#1: In ifelse(df <= 1, NA, exp(lgamma(df/2) - log(sqrt(df/2)) - lgamma((df -  :
#  value out of range in 'lgamma'
#(...)

I understand (e.g., from this answer) that the third (FALSE) argument of ifelse() is evaluated even when the condition is TRUE (and inversely if I change the order of the condition and the arguments)... But I simply don't know how to solve that (except maybe for hiding warnings before and after...).

(Note: I also tried dplyr::case_when(), but it is exactly the same problem.)


Solution

  • I'm pretty sure the values are calculated regardless, and just subset out by ifelse. You could always just apply your function to the valid values and make the rest NA:

    hedges_c <- function(df) {
      ss <- df >= 1
    
      hc <- function(x) exp(lgamma(x / 2) - log(sqrt(x / 2)) - lgamma((x - 1)/2))
    
      df[ss]  <- hc(df[ss])
      df[!ss] <- NA
      df
    }
    
    hedges_c(c(0, 0, 20, 14, 0, 0, 0, 0))
    #[1]        NA        NA 0.9619445 0.9452877        NA        NA        NA        NA