org - Media geométrica: ¿hay un built-in?
r studio (7)
Traté de encontrar un built-in para la media geométrica pero no pude.
(Obviamente, un built-in no me va a salvar en ningún momento mientras trabajaba en el shell, ni sospecho que haya alguna diferencia en la precisión, para los scripts trato de usar complementos tan a menudo como sea posible, donde el (acumulativo) la ganancia de rendimiento a menudo es notable.
En caso de que no haya uno (que dudo que sea el caso) aquí está el mío.
gm_mean = function(a){prod(a)^(1/length(a))}
Aquí hay una función vectorizada, cero y NA tolerante para calcular la media geométrica en R. El cálculo de la mean
verbosa que involucra la length(x)
es necesaria para los casos en que x
contiene valores no positivos.
gm_mean = function(x, na.rm=TRUE){
exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}
Gracias a @ ben-bolker por notar el paso de na.rm y @Gregor por asegurarse de que funciona correctamente.
Creo que algunos de los comentarios están relacionados con una falsa equivalencia de los valores de NA
en los datos y ceros. En la aplicación que tenía en mente, son los mismos, pero por supuesto esto no es verdad en general. Por lo tanto, si desea incluir la propagación opcional de ceros, y tratar la length(x)
diferente en el caso de la eliminación de NA
, la siguiente es una alternativa ligeramente más larga que la función anterior.
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))
}
}
Tenga en cuenta que también comprueba si hay valores negativos, y devuelve un NaN
más informativo y apropiado respetando que la media geométrica no está definida para los valores negativos (pero es para ceros). Gracias a los comentaristas que se quedaron en mi caso sobre esto.
El paquete EnvStats tiene una función para geoMean y geoSd
En caso de que falten valores en sus datos, este no es un caso raro. necesitas agregar un argumento más Puede intentar seguir los códigos.
exp(mean(log(i[is.finite(log(i))]),na.rm=T))
No, pero hay algunas personas que han escrito una, como here .
Otra posibilidad es usar esto:
exp(mean(log(x)))
Yo uso exactamente lo que dice Mark. De esta forma, incluso con tapply, puede usar la función mean
incorporada, ¡no es necesario definir la suya! Por ejemplo, para calcular medios geométricos por grupo de datos $ valor:
exp(tapply(log(data$value), data$group, mean))
los
exp(mean(log(x)))
funcionará a menos que haya un 0 en x. Si es así, el registro producirá -Inf (-Infinito) que siempre resulta en una media geométrica de 0.
Una solución es eliminar el valor de -Inf antes de calcular la media:
geo_mean <- function(data) {
log_data <- log(data)
gm <- exp(mean(log_data[is.finite(log_data)]))
return(gm)
}
Puede usar un trazador de líneas para hacer esto, pero significa calcular el registro dos veces, lo cual es ineficiente.
exp(mean(log(i[is.finite(log(i))])))
puedes usar el paquete psych
y llamar a geometric.mean
función geometric.mean
en eso.