기하 평균에 대한 내장을 찾으려고했지만 찾을 수 없었습니다.
(분명히 빌트인은 쉘에서 작업하는 동안 저를 절약 할 수 없으며 정확도에 차이가 있다고 생각하지 않습니다. 스크립트의 경우 빌트인을 가능한 한 자주 사용하려고합니다. 성능 향상은 종종 눈에 띄게 나타납니다.
(내가 의심하는) 하나가 없다면 여기 내 것입니다.
gm_mean = function(a){prod(a)^(1/length(a))}
답변
다음은 R에서 기하 평균을 계산하기위한 벡터화 된 0 및 NA 허용 함수입니다. 포함 된 자세한 mean
계산 length(x)
은 x
양수가 아닌 값을 포함 하는 경우에 필요 합니다.
gm_mean = function(x, na.rm=TRUE){
exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}
na.rm
통과 에 주목 해 주신 @ ben-bolker 와 올바르게 작동하는지 확인한 @Gregor에게 감사드립니다 .
의견 중 일부 NA
는 데이터 및 0 값 의 잘못된 동등성과 관련이 있다고 생각 합니다. 응용 프로그램에서 나는 그것들이 동일하다는 것을 염두에 두었지만 물론 이것은 일반적으로 사실이 아닙니다. 따라서 0의 선택적 전파를 포함하고 제거 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))
}
}
또한 음수 값을 확인 NaN
하고 기하 평균이 음수 값에 대해 정의되지 않았다는 점을 고려 하여 더 유익하고 적절한 결과를 반환 합니다 (하지만 0에 대한 것임). 이것에 대해 내 사건에 남아있는 논평자들에게 감사드립니다.
답변
답변
우리는 psych 패키지 를 사용 하고 geometric.mean 함수를 호출 할 수 있습니다 .
답변
그만큼
exp(mean(log(x)))
x에 0이 없으면 작동합니다. 그렇다면 로그는 항상 기하 평균이 0 인 -Inf (-Infinite)를 생성합니다.
한 가지 해결책은 평균을 계산하기 전에 -Inf 값을 제거하는 것입니다.
geo_mean <- function(data) {
log_data <- log(data)
gm <- exp(mean(log_data[is.finite(log_data)]))
return(gm)
}
한 줄짜리를 사용하여이를 수행 할 수 있지만 이는 비효율적 인 로그를 두 번 계산하는 것을 의미합니다.
exp(mean(log(i[is.finite(log(i))])))
답변
마크가 말한 그대로 사용합니다. 이렇게하면 tapply를 사용해도 내장 mean
기능을 사용할 수 있으며, 자신의 기능을 정의 할 필요가 없습니다! 예를 들어, data $ value의 그룹 별 기하학적 평균을 계산하려면 다음을 수행하십시오.
exp(tapply(log(data$value), data$group, mean))
답변
이 버전은 다른 답변보다 더 많은 옵션을 제공합니다.
-
이를 통해 사용자는 (실제) 숫자가 아닌 결과와 사용할 수없는 결과를 구분할 수 있습니다. 음수가 있으면 답은 실수
NaN
가 아니므 로 반환됩니다. 모든NA
값이 있으면 함수는NA_real_
대신 실제 값을 사용할 수 없음을 반영하여 반환 합니다. 이것은 미묘한 차이이지만 (약간) 더 강력한 결과를 얻을 수 있습니다. -
첫 번째 선택적 매개 변수
zero.rm
는 사용자가 0을 0으로 만들지 않고 출력에 영향을주는 0을 갖도록하기위한 것입니다. 경우zero.rm
로 설정FALSE
하고eta
로 설정NA_real_
(기본값), 제로 한 방향으로 결과를 축소의 효과가 있습니다. 나는 이것에 대한 이론적 정당성을 가지고 있지 않다. 단지 0을 무시하지 않고 자동으로 결과를 0으로 만드는 것을 포함하지 않는 “무언가”하는 것이 더 합리적이다. -
eta
https://support.bioconductor.org/p/64014/ 토론에서 영감을 얻은 0을 처리하는 방법입니다.
geomean <- function(x,
zero.rm = TRUE,
na.rm = TRUE,
nan.rm = TRUE,
eta = NA_real_) {
nan.count <- sum(is.nan(x))
na.count <- sum(is.na(x))
value.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
#Handle cases when there are negative values, all values are missing, or
#missing values are not tolerated.
if ((nan.count > 0 & !nan.rm) | any(x < 0, na.rm = TRUE)) {
return(NaN)
}
if ((na.count > 0 & !na.rm) | value.count == 0) {
return(NA_real_)
}
#Handle cases when non-missing values are either all positive or all zero.
#In these cases the eta parameter is irrelevant and therefore ignored.
if (all(x > 0, na.rm = TRUE)) {
return(exp(mean(log(x), na.rm = TRUE)))
}
if (all(x == 0, na.rm = TRUE)) {
return(0)
}
#All remaining cases are cases when there are a mix of positive and zero
#values.
#By default, we do not use an artificial constant or propagate zeros.
if (is.na(eta)) {
return(exp(sum(log(x[x > 0]), na.rm = TRUE) / value.count))
}
if (eta > 0) {
return(exp(mean(log(x + eta), na.rm = TRUE)) - eta)
}
return(0) #only propagate zeroes when eta is set to 0 (or less than 0)
}