Intenté encontrar una media geométrica incorporada pero no pude.
(Obviamente, un integrado no me va a ahorrar tiempo mientras trabajo en el shell, ni sospecho que haya ninguna diferencia en la precisión; para los scripts, trato de usar los elementos integrados con la mayor frecuencia posible, donde el (acumulativo) El aumento de rendimiento suele ser 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))}
Respuestas:
Aquí hay una función vectorizada, tolerante a cero y NA para calcular la media geométrica en R. El
mean
cálculo detallado que involucralength(x)
es necesario para los casos dondex
contiene valores no positivos.Gracias a @ ben-bolker por señalar la
na.rm
transferencia y a @Gregor por asegurarse de que funciona correctamente.Creo que algunos de los comentarios están relacionados con una falsa equivalencia de
NA
valores en los datos y ceros. En la aplicación que tenía en mente, son iguales, pero por supuesto, esto no es cierto en general. Por lo tanto, si desea incluir la propagación opcional de ceros y tratar lalength(x)
diferencia de manera diferente en el caso de laNA
eliminación, la siguiente es una alternativa un poco más larga a la función anterior.Tenga en cuenta que también comprueba los valores negativos y devuelve un valor más informativo y apropiado
NaN
respetando que la media geométrica no está definida para valores negativos (pero sí para ceros). Gracias a los comentaristas que se quedaron en mi caso sobre esto.fuente
na.rm
como un argumento (es decir, dejar que el usuario decida si quiere ser tolerante a NA o no, por coherencia con otras funciones de resumen de R)? Estoy nervioso por la exclusión automática de ceros; también lo haría una opción.na.rm
como una opción. Actualizaré mi respuesta. En cuanto a la exclusión de ceros, la media geométrica no está definida para valores no positivos, incluidos los ceros. Lo anterior es una solución común para la media geométrica, en la que a los ceros (o en este caso a todos los que no son cero) se les da un valor ficticio de 1, que no tiene ningún efecto sobre el producto (o, de manera equivalente, cero en la suma logarítmica).na.rm
transferencia no funciona según lo codificado ... veagm_mean(c(1:3, NA), na.rm = T)
. Debe eliminar el& !is.na(x)
del subconjunto de vectores y, dado que el primer argumento desum
es...
, debe pasarna.rm = na.rm
por el nombre y también debe excluir0
los yNA
del vector en lalength
llamada.x
contener solo cero (s), comox <- 0
,exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))
da1
para la media geométrica, que no tiene sentido.No, pero hay algunas personas que han escrito uno, como aquí .
Otra posibilidad es usar esto:
fuente
Podemos usar el paquete psych y llamar a la función geometric.mean .
fuente
psych::geometric.mean()
los
funcionará a menos que haya un 0 en x. Si es así, el registro producirá -Inf (-Infinite) que siempre resulta en una media geométrica de 0.
Una solución es eliminar el valor -Inf antes de calcular la media:
Puede usar una sola línea para hacer esto, pero significa calcular el registro dos veces, lo cual es ineficiente.
fuente
sum(x) / length(x)
es incorrecto si filtra x y luego se lo pasa amean
.Utilizo exactamente lo que dice Mark. De esta manera, incluso con tapply, puede usar la
mean
función incorporada, ¡sin necesidad de definir la suya! Por ejemplo, para calcular medias geométricas por grupo de datos $ valor:fuente
Esta versión ofrece más opciones que las otras respuestas.
Permite al usuario distinguir entre resultados que no son números (reales) y aquellos que no están disponibles. Si hay números negativos, entonces la respuesta no será un número real, por lo que
NaN
se devuelve. Si son todos losNA
valores, la función volverá en suNA_real_
lugar para reflejar que un valor real literalmente no está disponible. Esta es una diferencia sutil, pero una que podría producir resultados (ligeramente) más sólidos.El primer parámetro opcional
zero.rm
está destinado a permitir que el usuario tenga ceros que afecten la salida sin convertirla en cero. Sizero.rm
se establece enFALSE
yeta
se establece enNA_real_
(su valor predeterminado), los ceros tienen el efecto de reducir el resultado a uno. No tengo ninguna justificación teórica para esto, simplemente parece tener más sentido no ignorar los ceros sino "hacer algo" que no implique hacer automáticamente el resultado cero.eta
es una forma de manejar ceros que se inspiró en la siguiente discusión: https://support.bioconductor.org/p/64014/fuente
dplyr
para dicha utilidad a menos que sea necesario ...)case_when
s eran un poco tontos, así que los eliminé y la dependencia a favor deif
s. También proporcioné algunos detalles.nan.rm
aTRUE
alinear las tres `` `parámetros .rm``.ifelse
está diseñado para vectorización. Con una sola condición para verificar, sería más idiomático de usarvalue.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
ifelse
. Cambiado. ¡Gracias!El paquete EnvStats tiene una función para geoMean y geoSd .
fuente
En caso de que falten valores en sus datos, este no es un caso raro. necesitas agregar un argumento más.
Puede probar el siguiente código:
fuente
fuente