避免来自 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)即使条件为 TRUE
,ifelse()
的第三个 (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
并且警告消失了。
我创建了一个用户函数来计算 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)即使条件为 TRUE
,ifelse()
的第三个 (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
并且警告消失了。