組み込みの幾何平均を見つけようとしましたが、見つかりませんでした。
(明らかに、ビルトインはシェルでの作業中に時間を節約するつもりはありません。また、精度に違いがあるとは思わないでしょう。スクリプトでは、ビルトインを可能な限り頻繁に使用しようとします(累積)多くの場合、パフォーマンスの向上が顕著です。
ない場合(私はそうではありません)は、ここにあります。
gm_mean = function(a){prod(a)^(1/length(a))}
組み込みの幾何平均を見つけようとしましたが、見つかりませんでした。
(明らかに、ビルトインはシェルでの作業中に時間を節約するつもりはありません。また、精度に違いがあるとは思わないでしょう。スクリプトでは、ビルトインを可能な限り頻繁に使用しようとします(累積)多くの場合、パフォーマンスの向上が顕著です。
ない場合(私はそうではありません)は、ここにあります。
gm_mean = function(a){prod(a)^(1/length(a))}
回答:
これは、Rの幾何平均を計算するためのベクトル化されたゼロ許容関数とNA許容関数です。非正値が含まれている場合は、詳細なmean
計算length(x)
が必要x
です。
gm_mean = function(x, na.rm=TRUE){
exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}
パススルーに注意してくれた@ 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))
}
}
また、負の値もチェックしNaN
、幾何平均が負の値に対して定義されていない(ただし、ゼロに対する)ことを考慮して、より有益で適切な値を返します。これについて私の事件に留まったコメント者に感謝します。
na.rm
引数として渡す方が良いのではないでしょうか(つまり、他のRサマリー関数との一貫性を保つために、NAを許容するかどうかをユーザーに決定させます)。私はゼロを自動的に除外することに不安を感じています-私もそれをオプションにします。
na.rm
オプションとして渡すことについて正しいです。回答を更新します。ゼロの除外に関しては、ゼロを含む非正の値の幾何平均は定義されていません。上記は幾何平均の一般的な修正で、ゼロ(またはこの場合はすべての非ゼロ)に1のダミー値が与えられます。これは、積(または、対数合計のゼロ)に影響を与えません。
na.rm
パススルーコード化されたように動作しません...参照gm_mean(c(1:3, NA), na.rm = T)
。& !is.na(x)
ベクトルのサブセットからを削除する必要があり、sum
is の最初の引数は名前で...
渡すna.rm = na.rm
必要があるため、呼び出しでベクトルから0
とを除外する必要もあります。NA
length
x
だけにゼロ(複数可)を含む、のようなx <- 0
、exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))
与え1
意味をなさない幾何平均、のために。
psychパッケージを使用して、geometric.mean関数を呼び出すことができます。
psych::geometric.mean()
の
exp(mean(log(x)))
xに0がなければ機能します。その場合、ログは-Inf(-Infinite)を生成し、常に幾何平均が0になります。
1つの解決策は、平均を計算する前に-Inf値を削除することです。
geo_mean <- function(data) {
log_data <- log(data)
gm <- exp(mean(log_data[is.finite(log_data)]))
return(gm)
}
これを行うにはワンライナーを使用できますが、これはログを2回計算することを意味し、非効率的です。
exp(mean(log(i[is.finite(log(i))])))
sum(x) / length(x)
xをフィルタリングしてに渡すと、平均値が間違っているため、平均値が間違っていますmean
。
このバージョンは、他の回答よりも多くのオプションを提供します。
これにより、ユーザーは(実際の)数値ではない結果と使用できない結果を区別できます。負の数が存在する場合、答えは実数ではないため、NaN
返されます。すべてのNA
値の場合、関数はNA_real_
代わりに戻り、実際の値が文字通り利用できないことを反映します。これは微妙な違いですが、(少し)より堅牢な結果が得られる可能性があります。
最初のオプションのパラメーターzero.rm
は、ユーザーがゼロにすることなく、出力に影響を与えることができるようにすることを目的としています。場合zero.rm
に設定されているFALSE
とeta
に設定されているNA_real_
(デフォルト値)、ゼロが1に向かって結果を縮小する効果を有します。私はこれに対する理論的な正当化はありません-ゼロを無視するのではなく、結果を自動的にゼロにすることを含まない「何かをする」ことの方が理にかなっているようです。
eta
次のディスカッションに触発されてゼロを処理する方法です:https : //support.bioconductor.org/p/64014/
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)
}
dplyr
必要でない限り、そのようなユーティリティのような重い依存関係を追加したくありません...)
case_when
sは少しばかげたので、それらを削除してif
s を優先しました。詳細についても説明しました。
nan.rm
をTRUE
に変更して、3つの `` `.rm``パラメータすべてを揃えます。
ifelse
ベクトル化のために設計されています。単一の条件をチェックするので、使用する方が慣用的ですvalue.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
ifelse
がいいです。かわった。ありがとう!
EnvStatsパッケージはのための機能を有する幾何平均とgeoSdを。
exp(mean(log(x1))) == prod(x1)^(1/length(x1))