dou*_*oug 94 statistics r built-in geometric-mean
我试图找到几何平均值的内置但不能.
(显然,在shell中工作时内置不会保存我,也不会怀疑在准确性上有任何差异;对于脚本,我尝试尽可能多地使用内置函数,其中(累积)性能提升通常是显而易见的.
如果没有一个(我怀疑是这种情况),这里是我的.
gm_mean = function(a){prod(a)^(1/length(a))}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 82
不,但是有一些人写了一个,比如这里.
另一种可能性是使用这个:
exp(mean(log(x)))
Run Code Online (Sandbox Code Playgroud)
Pau*_*die 67
这是一个矢量化,零和NA容忍函数,用于计算R中的几何平均值.对于包含非正值的情况,必须进行详细mean计算.length(x)x
gm_mean = function(x, na.rm=TRUE){
exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}
Run Code Online (Sandbox Code Playgroud)
感谢@ ben-bolker注意到na.rm传递和@Gregor以确保它正常工作.
我认为一些评论与NA数据和零中的值的假等价性有关.在应用程序中,我想到它们是相同的,但当然这通常不正确.因此,如果要包含零的可选传播,并length(x)在NA删除的情况下区别对待,则以下是上述函数的稍长的替代方法.
gm_mean = function(x, na.rm=TRUE, zero.propagate = FALSE){
if(any(x < 0, na.rm = TRUE)){
return(NaN)
}
if(zero.propagate){
if(any(x == 0, na.rm = TRUE)){
return(0)
}
exp(mean(log(x), na.rm = na.rm))
} else {
exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,它还检查任何负值,并返回更具信息性和适当的NaN尊重,即没有为负值定义几何平均值(但是为零).感谢评论此事的评论者.
小智 12
该
exp(mean(log(x)))
Run Code Online (Sandbox Code Playgroud)
除非x中有0,否则会有效.如果是这样,日志将产生-Inf(-Infinite),它总是导致几何平均值为0.
一种解决方案是在计算平均值之前删除-Inf值:
geo_mean <- function(data) {
log_data <- log(data)
gm <- exp(mean(log_data[is.finite(log_data)]))
return(gm)
}
Run Code Online (Sandbox Code Playgroud)
您可以使用单行来执行此操作,但这意味着计算两次日志效率很低.
exp(mean(log(i[is.finite(log(i))])))
Run Code Online (Sandbox Code Playgroud)
我正好用Mark所说的.这样,即使使用tapply,您也可以使用内置mean功能,无需定义您的!例如,要计算每组数据的几何平均值$ value:
exp(tapply(log(data$value), data$group, mean))
Run Code Online (Sandbox Code Playgroud)