20  R: Modular Approach

20.1 Function: Mean (AM, GM, HM)

  • Calculate AM, GM and HM of a numeric vector using the following formula.

Arithmetic Mean (AM)

\[ \large AM = (x_1 + x_2 + ... + x_n)/n = \frac{1}{n}\sum\limits_{i=1}^{n} x_{i}\]

Geometric Mean (GM)

\[ \large GM = \sqrt[n]{(x_1 x_2 ... x_n)} = \left( \prod \limits_{i=1}^{n} x_{i} \right) ^{\frac{1}{n}} \]

Harmonic Mean (HM)

\[ \large HM = \frac{n}{(\frac{1}{x_1} + \frac{1}{x_2} + ... + \frac{1}{x_n})} = \frac{1}{\frac{1}{n}\sum\limits_{i=1}^{n} \frac{1}{x_i}}\]

20.2 Functions: Modular approach

Note: The following script is for demonstration only to explain the structure of a function and modular approach to function call.

We are expanding all base functions without any obvious advantages here. A possible optimal version is shown in the next section.

Code
fn_n = function(x, na.rm = FALSE) ifelse(na.rm, length(na.omit(x)), length(x))

fn_sum = function(x, ...) sum(x, ...)

fn_prod = function(x, ...) prod(x, ...)

fn_suminv = function(x, ...) sum(1/x, ...)

fn_AM = function(x, ...) {
    out = fn_sum(x, ...)/fn_n(x, ...)
    return(out)
}

fn_GM = function(x, ...) {
    out = fn_prod(x, ...)^(1/fn_n(x, ...))
    return(out)
}

fn_HM = function(x, ...) {
    out = fn_n(x, ...)/fn_suminv(x, ...)
    return(out)
}


fn_Mean = function(x, ...) {

    n = fn_n(x, ...)

    AM = fn_AM(x, ...)
    GM = fn_GM(x, ...)
    HM = fn_HM(x, ...)

    Mean = list(n = n, AM = AM, GM = GM, HM = HM)

    return(Mean)
}

20.3 Data

Code
A = c(11, 12, 15, 14, 18)

B = c(NA, 12, 15, 14, 18)

20.4 Function call 1

Code
A_mean = fn_Mean(A)

A_mean
$n
[1] 5

$AM
[1] 14

$GM
[1] 13.79155

$HM
[1] 13.5909

20.5 Function call 2

Code
B_mean = fn_Mean(B, na.rm = TRUE)

B_mean
$n
[1] 4

$AM
[1] 14.75

$GM
[1] 14.5938

$HM
[1] 14.44126

20.6 Optimal version

We have all base functions available; a possible optimal version of the above function can be written as shown below.

Code
fn_Mean = function(x, ...) {
    fn_n = function(x, na.rm = FALSE) ifelse(na.rm, length(na.omit(x)), length(x))
    n = fn_n(x, ...)
    AM = mean(x, ...)
    GM = exp(mean(log(x), ...))
    HM = 1/mean(1/x, ...)
    Mean = list(n = n, AM = AM, GM = GM, HM = HM)
    return(Mean)
}