[R] geometric mean to handle large number and negative value

(Ted Harding) Ted.Harding at manchester.ac.uk
Wed Apr 15 12:14:30 CEST 2009


On 15-Apr-09 09:26:55, Richard.Cotton at hsl.gov.uk wrote:
>> I have created two functions to compute geometric means. Method 1 can
>> handle even number of negative values but not large number, vice versa
>> for method 2. How can I merge both functions so that both large number
>> and negative values can be handled ?
>> 
>> > geometric.mean1 <- function(x) prod(x)^(1/length(x))
>> > geometric.mean2 <- function(x) exp(mean(log(x)))
>> 
>> > geometric.mean1(1:10000000)
>> [1] Inf
>> > geometric.mean2(1:10000000)
>> [1] 3678798
>> 
>> > geometric.mean1(c(-5,-4,4,5))
>> [1] 4.472136
>> > geometric.mean2(c(-5,-4,4,5))
>> [1] NaN
>> Warning message:
>> In log(x) : NaNs produced
> 
> Geometric mean is usually restricted to positive inputs, because
> otherwise the answer can have an imaginary component. If you really
> want the geometric mean of negative inputs, use the second method
> but convert the input to be a complex number first.
> 
> comp.x <- as.complex(c(-5,-4,4,5))
> geometric.mean2(comp.x)
># [1] 0+4.472136i
> 
> Regards,
> Richie.
> Mathematical Sciences Unit
> HSL

Since it appears that you were content with the result of your product
method when there was an even number of negative cases, and this is
equivalent to the result you would get if all the negative numbers
were positive, why not simply convert all numbers to positive by
using abs(), and then applying your second method (which can cope
with large numbers)?

I.e. geometric.mean3 <- function(x) exp(mean(log(abs(x))))

However, do think carefully about whether the results will make the
sort of sense that you intend.

For instance, on that basis,

  geometric.mean3(c(-1,1)) = 1, not 0

  geometric.mean2(c(-4,-1)) = 2, so the resulting geometric mean
    is outside the range of the original numbers.

(yet it is what your first method would have given).

On the other hand, Richie's suggestion gives results which you may
consider to make more sense:

  comp.x <- as.complex(c(-1,1))
  geometric.mean2(comp.x)
  # [1] 0+1i

  comp.x <- as.complex(c(-4,-1))
  geometric.mean2(comp.x)
  # [1] -2+0i

But then, in the original example:

  comp.x <- as.complex(c(-5,-4,4,5))
  geometric.mean2(comp.x)
  # [1] 0+4.472136i

what do you want to do with the resulting 4.472136i ?

So you need to think about what you intend to do with the result,
in general, and about why you want to compute a geometric mean.

Ted.

--------------------------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk>
Fax-to-email: +44 (0)870 094 0861
Date: 15-Apr-09                                       Time: 11:14:27
------------------------------ XFMail ------------------------------




More information about the R-help mailing list