避免来自 ifelse() 的 FALSE 部分的警告

Avoid warnings from FALSE part of ifelse()

我创建了一个用户函数来计算 g 的 Hedges 的 c() 偏差校正(Hedges,1981)。它直接基于 library(metafor) 中的 metafor::.cmicalc() 函数。它这样做:

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

当应用于包含值 <= 1 的向量时,lgamma() 会生成警告,因为 lgamma(0)(以及任何负值)会生成 NaN。所以,我的解决方案(以及 metafor::.cmicalc() 所做的)包括一个 ifelse() 语句:

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

但是,这是我似乎没有找到解决方案的问题,它仍然会生成 warnings(),即使所有值都正确呈现为 NA

示例:

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'
#(...)

我了解到(例如,来自 this answer)即使条件为 TRUEifelse() 的第三个 (FALSE) 参数也会被求值(反之,如果我改变了条件和参数的顺序)...但我根本不知道如何解决这个问题(除了可能在...之前和之后隐藏警告)。

(注:我也试过dplyr::case_when(),但还是一模一样的问题。)

我很确定这些值是无论如何计算的,只是 ifelse 的子集。你总是可以只将你的函数应用于有效值并使其余的 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

尝试使用不同的方法。类似于以下内容。

hedges_c <- function(df) {
  cdf <- rep(NA, length(df))
  inx <- df > 1
  cdf[inx] <- exp(lgamma(df[inx] / 2) - log(sqrt(df[inx] / 2)) - lgamma((df[inx] - 1)/2))
  return(cdf)
}

hedges_c(c(0, 0, 20, 14, 0, 0, 0, 0))
#[1]        NA        NA 0.9619445 0.9452877        NA        NA        NA
#[8]        NA

并且警告消失了。