Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Geometric Mean: is there a built-in?

People also ask

How is geometric mean found?

Basically, we multiply the numbers altogether and take the nth root of the multiplied numbers, where n is the total number of data values. For example: for a given set of two numbers such as 3 and 1, the geometric mean is equal to √(3×1) = √3 = 1.732.

When should geometric mean be used?

In statistics, the geometric mean is calculated by raising the product of a series of numbers to the inverse of the total length of the series. The geometric mean is most useful when numbers in the series are not independent of each other or if numbers tend to make large fluctuations.

What are the properties of geometric mean?

The following are the properties of Geometric mean: The geometric mean for a given data is always less than the arithmetic means for a given data set. The ratio of the associated observation of the geometric mean in two series is equivalent to the ratio of their geometric means.

What does geometric mean represent?

The Geometric Mean (GM) is the average value or mean which signifies the central tendency of the set of numbers by finding the product of their values. In mathematics and statistics, measures of central tendencies describe the summary of whole data set values.


No, but there are a few people who have written one, such as here.

Another possibility is to use this:

exp(mean(log(x)))

Here is a vectorized, zero- and NA-tolerant function for calculating geometric mean in R. The verbose mean calculation involving length(x) is necessary for the cases where x contains non-positive values.

gm_mean = function(x, na.rm=TRUE){
  exp(sum(log(x[x > 0]), na.rm=na.rm) / length(x))
}

Thanks to @ben-bolker for noting the na.rm pass-through and @Gregor for making sure it works correctly.

I think some of the comments are related to a false-equivalency of NA values in the data and zeros. In the application I had in mind they are the same, but of course this is not generally true. Thus, if you want to include optional propagation of zeros, and treat the length(x) differently in the case of NA removal, the following is a slightly longer alternative to the function above.

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))
  }
}

Note that it also checks for any negative values, and returns a more informative and appropriate NaN respecting that geometric mean is not defined for negative values (but is for zeros). Thanks to commenters who stayed on my case about this.


We can use psych package and call geometric.mean function.


The

exp(mean(log(x)))

will work unless there is a 0 in x. If so, the log will produce -Inf (-Infinite) which always results in a geometric mean of 0.

One solution is to remove the -Inf value before calculating the mean:

geo_mean <- function(data) {
    log_data <- log(data)
    gm <- exp(mean(log_data[is.finite(log_data)]))
    return(gm)
}

You can use a one-liner to do this but it means calculating the log twice which is inefficient.

exp(mean(log(i[is.finite(log(i))])))

I use exactly what Mark says. This way, even with tapply, you can use the built-in mean function, no need to define yours! For example, to compute per-group geometric means of data$value:

exp(tapply(log(data$value), data$group, mean))