【问题标题】:Avoid warnings from FALSE part of ifelse()避免来自 ifelse() 的 FALSE 部分的警告
【发布时间】:2017-11-23 22:16:30
【问题描述】:

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

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

当应用于包含值 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)
}

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

例子:

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 answerifelse() 的第三个 (FALSE) 参数即使在条件为 TRUE 时也会被评估(相反,如果我更改条件和参数的顺序)...但我根本不知道如何解决这个问题(除了可能隐藏之前和之后的警告...)。

(注:我也试过dplyr::case_when(),但问题完全一样。)

【问题讨论】:

  • 您是否尝试使用if(...) { ... } else { ... } 而不是ifelse(...,...,...)
  • @Heikki:是的,但是当应用于矢量时它不能正常工作。 ifelse() 允许对其进行矢量化。

标签: r if-statement metafor


【解决方案1】:

我很确定这些值是无论如何计算出来的,只是由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

【讨论】:

  • 作为对您对我的回答的评论的回答,我相信您是对的,我记得读过ifelse 的源代码,我的印象是它创建了两个向量,yesno,然后是子集。我不确定,现在没有时间,但明天会回到这个。
  • 我用casewhen 测试过,它还计算所有值
  • @Moody_Mudskipper - 是的,case_when 只是创建了每个比较的所有逻辑结果的大列表,然后循环遍历它们以查找第一个 TRUE 值。这就是为什么其余情况总是TRUE ~ ... 你可以通过cbind-ing 每个比较并调用max.col(result, "first") 来近似case_when
  • 你和我是对的,ifelse 的最后几行是向量ans 的子集。
【解决方案2】:

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

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

警告消失了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多