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
meancálculo detallado que involucralength(x)es necesario para los casos dondexcontiene valores no positivos.Gracias a @ ben-bolker por señalar la
na.rmtransferencia y a @Gregor por asegurarse de que funciona correctamente.Creo que algunos de los comentarios están relacionados con una falsa equivalencia de
NAvalores 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 laNAeliminació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
NaNrespetando 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.rmcomo 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.rmcomo 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.rmtransferencia 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 desumes..., debe pasarna.rm = na.rmpor el nombre y también debe excluir0los yNAdel vector en lalengthllamada.xcontener solo cero (s), comox <- 0,exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))da1para 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
meanfunció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
NaNse devuelve. Si son todos losNAvalores, 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.rmestá destinado a permitir que el usuario tenga ceros que afecten la salida sin convertirla en cero. Sizero.rmse establece enFALSEyetase 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.etaes una forma de manejar ceros que se inspiró en la siguiente discusión: https://support.bioconductor.org/p/64014/fuente
dplyrpara dicha utilidad a menos que sea necesario ...)case_whens eran un poco tontos, así que los eliminé y la dependencia a favor deifs. También proporcioné algunos detalles.nan.rmaTRUEalinear las tres `` `parámetros .rm``.ifelseestá 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