Я пытался найти встроенную функцию для среднего геометрического, но не смог.
(Очевидно, что встроенный модуль не спасет меня в любое время при работе в оболочке, и я не подозреваю, что есть какая-либо разница в точности; для скриптов я стараюсь использовать встроенные модули как можно чаще, где (совокупный) прирост производительности часто заметен.
Если его нет (в чем я сомневаюсь), вот мой.
gm_mean = function(a){prod(a)^(1/length(a))}
Ответы:
Вот векторизованная, допускающая ноль и NA функция для вычисления среднего геометрического в R. Подробное
mean
вычислениеlength(x)
необходимо для случаев, когда онаx
содержит неположительные значения.Спасибо @ ben-bolker за то, что отметили
na.rm
сквозной переход, и @Gregor за то, что он работает правильно.Я думаю, что некоторые комментарии связаны с ложной эквивалентностью
NA
значений в данных и нулями. В приложении, которое я имел в виду, они такие же, но, конечно, в целом это не так. Таким образом, если вы хотите включить необязательное распространение нулей и относиться к нему по-length(x)
другому в случаеNA
удаления, следующее является немного более длинной альтернативой функции, описанной выше.Обратите внимание, что он также проверяет любые отрицательные значения и возвращает более информативное и подходящее,
NaN
учитывая, что среднее геометрическое не определено для отрицательных значений (а предназначено для нулей). Спасибо комментаторам, которые остались в моем случае по этому поводу.источник
na.rm
в качестве аргумента (т.е. позволить пользователю решить, хотят ли они быть NA-толерантными или нет, для согласованности с другими сводными функциями R)? Я нервничаю по поводу автоматического исключения нулей - я бы тоже сделал это опцией.na.rm
в качестве варианта. Я обновлю свой ответ. Что касается исключения нулей, среднее геометрическое не определено для неположительных значений, включая нули. Вышеупомянутое является обычным исправлением для среднего геометрического, в котором нулям (или в данном случае всем ненулевым) присваивается фиктивное значение 1, которое не влияет на продукт (или, что эквивалентно, ноль в логарифмической сумме).na.rm
сквозной канал работает не так, как закодировано ... понимаетеgm_mean(c(1:3, NA), na.rm = T)
. Вам нужно удалить& !is.na(x)
из подмножества векторов, и, поскольку первый аргументsum
равен...
, вам нужно передатьna.rm = na.rm
по имени, и вам также нужно исключить0
иNA
из вектора вlength
вызове.x
содержащие только ноль (ы), какx <- 0
,exp(sum(log(x[x>0]), na.rm = TRUE)/length(x))
дает1
для среднего геометрического, который не имеет смысла.Нет, но есть несколько человек, которые написали один, например, здесь .
Другая возможность - использовать это:
источник
Мы можем использовать психологический пакет и вызвать geometric.mean функции.
источник
psych::geometric.mean()
В
будет работать, если в x нет 0. Если это так, журнал выдаст -Inf (-Infinite), что всегда приводит к среднему геометрическому 0.
Одно из решений - удалить значение -Inf перед вычислением среднего:
Для этого можно использовать однострочник, но это означает двойное вычисление журнала, что неэффективно.
источник
sum(x) / length(x)
неверен, если вы отфильтруете x, а затем передадите его вmean
.Я использую именно то, что говорит Марк. Таким образом, даже с tapply, вы можете использовать встроенную
mean
функцию, вам не нужно определять свою! Например, чтобы вычислить среднее геометрическое значение $ value для каждой группы:источник
Эта версия предоставляет больше возможностей, чем другие ответы.
Это позволяет пользователю различать результаты, которые не являются (реальными) числами, и те, которые недоступны. Если присутствуют отрицательные числа, ответ не будет действительным числом, поэтому он
NaN
будет возвращен. Если это всеNA
значения, тогда функция вернется,NA_real_
чтобы отразить, что реальное значение буквально недоступно. Это небольшое различие, но оно может дать (немного) более надежные результаты.Первый необязательный параметр
zero.rm
предназначен для того, чтобы позволить пользователю иметь нули, влияющие на вывод, не делая его нулевым. Еслиzero.rm
установленоFALSE
иeta
установленоNA_real_
(значение по умолчанию), нули приводят к уменьшению результата до единицы. У меня нет никакого теоретического обоснования для этого - просто кажется более разумным не игнорировать нули, а «сделать что-то», что не предполагает автоматического обнуления результата.eta
это способ обработки нулей, вдохновленный следующим обсуждением: https://support.bioconductor.org/p/64014/источник
dplyr
для такой утилиты, если в этом нет необходимости ...)case_when
s были немного глупыми, поэтому я удалил их и зависимость в пользуif
s. Я также внес некоторые уточнения.nan.rm
на,TRUE
чтобы выровнять все три параметра `` .rm``.ifelse
предназначен для векторизации. С единственным условием для проверки было бы более идиоматично использоватьvalue.count <- if(zero.rm) sum(x[!is.na(x)] > 0) else sum(!is.na(x))
ifelse
тоже. Изменено. Спасибо!В пакете EnvStats есть функция для geoMean и geoSd .
источник
Если в ваших данных отсутствуют значения, это не редкость. вам нужно добавить еще один аргумент.
Вы можете попробовать следующий код:
источник
источник