R 几何平均值:是否有内置的?

R 几何平均值:是否有内置的?,r,statistics,built-in,geometric-mean,R,Statistics,Built In,Geometric Mean,我试图找到一个内置的几何平均数,但无法 显然,在shell中工作时,内置软件不会节省我任何时间,我也不怀疑在准确性上有任何区别;对于脚本,我尝试尽可能多地使用内置程序,其中累积的性能增益通常是显而易见的 如果没有一个我怀疑是这样的话,这是我的 gm_mean = function(a){prod(a)^(1/length(a))} 没有,但是有一些人写过一本,比如 另一种可能是使用以下方法: exp(mean(log(x))) 我完全按照马克说的去做。这样,即使使用tapply,您也可以使用

我试图找到一个内置的几何平均数,但无法

显然,在shell中工作时,内置软件不会节省我任何时间,我也不怀疑在准确性上有任何区别;对于脚本,我尝试尽可能多地使用内置程序,其中累积的性能增益通常是显而易见的

如果没有一个我怀疑是这样的话,这是我的

gm_mean = function(a){prod(a)^(1/length(a))}

没有,但是有一些人写过一本,比如

另一种可能是使用以下方法:

exp(mean(log(x)))

我完全按照马克说的去做。这样,即使使用tapply,您也可以使用内置的均值函数,无需定义您的均值函数!例如,要计算数据$value的每组几何平均值:

exp(tapply(log(data$value), data$group, mean))
我们可以使用和调用geometric.mean函数。

exp(mean(log(x)))
除非x中有一个0,否则将正常工作。如果是这样,日志将生成-Inf-Infinite,这将始终导致几何平均值为0

一种解决方案是在计算平均值之前删除-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)) ]), na.rm = TRUE))

这是一个矢量化、零和NA容差函数,用于计算R中的几何平均值。对于x包含非正值的情况,需要进行涉及lengthx的详细平均值计算

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值和零的错误等效性有关。在我心目中的应用程序中,它们是相同的,但当然这通常不是真的。因此,如果您希望包括可选的零传播,并在去除NA的情况下以不同的方式处理lengthx,则以下是上述函数的稍长替代方案

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,即几何平均值不是为负值定义的,而是为零定义的。感谢一直关注我的案例的评论者。

具有geoMean和geoSd功能。

此版本提供了比其他答案更多的选项

它允许用户区分不是实数的结果和不可用的结果。如果存在负数,则答案将不是实数,因此返回NaN。如果它都是NA值,那么函数将返回NA_real_u,以反映实际值实际上不可用。这是一个细微的差别,但可能会产生稍微更稳健的结果

第一个可选参数zero.rm旨在允许用户让零影响输出,而不使其为零。如果zero.rm设置为FALSE,而eta设置为NA_real__________________________________。我没有任何理论上的理由来证明这一点——不忽略零似乎更有意义,但是做一些不涉及自动将结果置零的事情

eta是一种处理零的方法,其灵感来源于以下讨论:

几何平均值0,na.rm=TRUE{ returnexpmeanlogx,na.rm=TRUE } 如果allx==0,则na.rm=TRUE{ 返回0 } 所有剩余的情况都是正和零混合的情况 价值观 默认情况下,我们不使用人工常数或传播零。 如果是奈塔{ returnexpsumlogx[x>0],na.rm=TRUE/value.count } 如果eta>0{ returnexpmeanlogx+预计到达时间,na.rm=真-预计到达时间 } return0仅在eta设置为0或小于0时传播零 }
注意负数和溢出。proda将很快被压下或溢出。我尝试使用一个大列表来计时,并使用您的方法vs 1.4和expmeanlogx快速获得Inf;舍入问题可能相当严重。我只是快速编写了上面的函数,因为我确信在发布此问题5分钟后,有人会告诉我R是gm的内置函数。因此没有内置函数,因此根据您的评论,花时间重新编码肯定是值得的1.我刚刚标记了这个,9年后。如果可以,为什么要计算两次对数:expmeanx[x!=0]两种方法的平均值都是错误的,因为平均值的分母,如果你过滤x,然后将其传递给mean,那么sumx/lengthx是错误的。我认为过滤是一个坏主意,除非你明确表示要这样做。例如,如果我正在编写一个通用函数,我不会将过滤设为默认值-如果这是一段一次性代码,并且你已经非常仔细地考虑过过滤零实际上意味着什么你问题的背景!根据定义,包含零的一组数字的几何平均值应该是零!是否最好将na.rm作为参数传递给用户,即让用户决定是否要容忍na,以便与其他R摘要函数保持一致?我担心自动排除零
es-我也会把它作为一个选项。也许你把na.rm作为一个选项是对的。我会更新我的答案。至于排除零,几何平均值对于包括零在内的非正值是未定义的。以上是几何平均值的常见固定值,其中零或在本例中所有非零都被赋予一个虚拟值1,该值对乘积没有影响,或等效地,对数和中的零。您的na.rm传递不按编码方式工作。。。参见gm_Means C1:3,NA,NA.rm=T。您需要拆下&!is.nax来自向量子集,并且由于sum的第一个参数是…,您需要通过名称传递na.rm=na.rm,还需要在长度调用中从向量中排除0和na。注意:对于仅包含零的x,如x 0],na.rm=TRUE/lengthx的几何平均值为1,这没有意义。假设na.rm=TRUE,它不是一定要像lengthx[!is.nax&x>0]吗?使用expmeanlogx的另一个优点是,您可以处理大量的长列表,当使用更明显的公式使用prod时,这是有问题的。请注意,proda ^1/lengtha和EXPMANLOGA给出了相同的答案。链接已修复Psych::geometric。意思这些函数应采用序列,而不是它们的增长,至少作为选项,我想说。你能补充一些细节来解释这与现有解决方案的区别/改进吗?我个人不想为这样一个实用程序添加像dplyr这样的严重依赖项,除非有必要……我同意,当时的情况有点傻,所以我删除了它们和依赖项,支持ifs。我还提供了一些详细说明。我采用了您的后一个想法,将nan.rm的默认值更改为TRUE,以对齐所有三个“.rm”参数。还有一个风格上的挑剔。ifelse是为矢量化而设计的。如果只需检查一个条件,则使用value.count 0 else sum更为惯用!纳希特看起来也比其他人好。改变。谢谢
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))
  }
}
exp(mean(log(x1))) == prod(x1)^(1/length(x1))