Saya mencoba menemukan built-in untuk mean geometris tetapi tidak bisa.
(Jelas built-in tidak akan menyelamatkan saya kapan saja saat bekerja di shell, saya juga tidak curiga ada perbedaan dalam akurasi; untuk skrip saya mencoba menggunakan built-in sesering mungkin, di mana (kumulatif) peningkatan kinerja sering kali terlihat.
Jika tidak ada satu (yang saya ragu adalah kasusnya), ini milik saya.
gm_mean = function(a){prod(a)^(1/length(a))}
Jawaban:
Berikut adalah fungsi vectorized, zero- dan NA-tolerant untuk menghitung rata-rata geometris di R.
mean
Perhitungan verbose yang melibatkanlength(x)
diperlukan untuk kasus-kasus di manax
mengandung nilai-nilai non-positif.Terima kasih kepada @ ben-bolker karena telah mencatat
na.rm
pass-through dan @Gregor untuk memastikannya berfungsi dengan benar.Saya pikir beberapa komentar terkait dengan kesetaraan
NA
nilai palsu dalam data dan nol. Dalam penerapan yang saya pikirkan, mereka sama, tetapi tentu saja ini tidak benar secara umum. Jadi, jika Anda ingin menyertakan penyebaran opsional dari nol, dan memperlakukan secaralength(x)
berbeda dalam kasusNA
penghapusan, berikut ini adalah alternatif yang sedikit lebih panjang untuk fungsi di atas.Perhatikan bahwa ini juga memeriksa nilai negatif apa pun, dan mengembalikan nilai yang lebih informatif dan tepat
NaN
sehubungan dengan rata-rata geometris tidak ditentukan untuk nilai negatif (tetapi untuk nol). Terima kasih kepada pemberi komentar yang tetap menangani kasus saya tentang ini.sumber
na.rm
sebagai argumen (yaitu biarkan pengguna memutuskan apakah mereka ingin toleran NA atau tidak, untuk konsistensi dengan fungsi ringkasan R lainnya)? Saya gugup tentang secara otomatis mengecualikan nol - saya akan menjadikannya sebagai pilihan juga.na.rm
sebagai opsi. Saya akan memperbarui jawaban saya. Adapun untuk mengecualikan nol, rata-rata geometris tidak ditentukan untuk nilai non-positif, termasuk nol. Di atas adalah fiksasi umum untuk rata-rata geometrik, di mana nol (atau dalam hal ini semua bukan nol) diberi nilai dummy 1, yang tidak berpengaruh pada hasil kali (atau ekuivalen, nol dalam jumlah logaritmik).na.rm
pass-through tidak bekerja sebagai kode ... lihatgm_mean(c(1:3, NA), na.rm = T)
. Anda perlu menghapus& !is.na(x)
dari subset vektor, dan karena argumen pertamasum
adalah...
, Anda harus memberikanna.rm = na.rm
nama, dan Anda juga perlu mengecualikan0
's danNA
' dari vektor saatlength
panggilan.x
hanya mengandung nol, sepertix <- 0
,exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))
memberikan1
mean geometrik, yang tidak masuk akal.Tidak, tapi ada beberapa orang yang pernah menulisnya, seperti di sini .
Kemungkinan lain adalah menggunakan ini:
sumber
Kita bisa menggunakan paket psych dan memanggil fungsi geometric.mean .
sumber
psych::geometric.mean()
Itu
akan bekerja kecuali ada 0 di x. Jika demikian, log akan menghasilkan -Inf (-Infinite) yang selalu menghasilkan mean geometrik 0.
Salah satu solusinya adalah menghapus nilai -Inf sebelum menghitung mean:
Anda dapat menggunakan satu baris untuk melakukan ini tetapi itu berarti menghitung log dua kali yang tidak efisien.
sumber
sum(x) / length(x)
salah jika Anda memfilter x dan meneruskannyamean
.Saya menggunakan persis apa yang dikatakan Mark. Dengan cara ini, bahkan dengan tapply, Anda dapat menggunakan
mean
fungsi bawaan , tidak perlu menentukan milik Anda! Misalnya, untuk menghitung rata-rata geometris per grup dari data $ value:sumber
Versi ini memberikan lebih banyak pilihan daripada jawaban lainnya.
Ini memungkinkan pengguna untuk membedakan antara hasil yang bukan bilangan (nyata) dan yang tidak tersedia. Jika ada angka negatif, jawabannya bukan bilangan real, jadi
NaN
dikembalikan. Jika itu semuaNA
nilai maka fungsinya akan kembaliNA_real_
untuk mencerminkan bahwa nilai sebenarnya secara harfiah tidak tersedia. Ini adalah perbedaan yang halus, tetapi mungkin menghasilkan (sedikit) hasil yang lebih kuat.Parameter opsional pertama
zero.rm
dimaksudkan agar pengguna memiliki nol yang memengaruhi keluaran tanpa menjadikannya nol. Jikazero.rm
disetel keFALSE
daneta
disetel keNA_real_
(nilai defaultnya), nol memiliki efek menyusutkan hasilnya ke satu. Saya tidak memiliki pembenaran teoretis untuk ini - sepertinya lebih masuk akal untuk tidak mengabaikan angka nol tetapi untuk "melakukan sesuatu" yang tidak melibatkan otomatis membuat hasil menjadi nol.eta
adalah cara menangani angka nol yang terinspirasi dari diskusi berikut: https://support.bioconductor.org/p/64014/sumber
dplyr
untuk utilitas seperti itu kecuali jika diperlukan ...)case_when
s itu agak konyol, jadi saya menghapusnya dan ketergantungan mendukungif
s. Saya juga memberikan beberapa elaborasi.nan.rm
menjadiTRUE
untuk menyelaraskan ketiga parameter ".rm``.ifelse
dirancang untuk vektorisasi. Dengan satu kondisi untuk diperiksa, akan lebih idiomatis untuk digunakanvalue.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
ifelse
. Berubah. Terima kasih!The EnvStats paket memiliki fungsi untuk GEOMEAN dan geoSd .
sumber
Jika ada nilai yang hilang dalam data Anda, ini bukan kasus yang jarang terjadi. Anda perlu menambahkan satu argumen lagi.
Anda dapat mencoba kode berikut:
sumber
sumber