Skip to contents

Transmute weights to turn a generalized mean of order \(r\) into a generalized mean of order \(s\). Useful for calculating additive and multiplicative decompositions for a generalized-mean index, and those made of nested generalized means (e.g., Fisher index).

Usage

transmute_weights(r, s)

nested_transmute(r1, r2, s, t = c(1, 1))

nested_transmute2(r1, r2, s, t = c(1, 1))

Arguments

r, s

A finite number giving the order of the generalized mean. See details.

r1

A finite number giving the order of the outer generalized mean.

r2

A pair of finite numbers giving the order of the inner generalized means.

t

A pair of strictly positive weights for the inner generalized means. The default is equal weights.

Value

transmute_weights() returns a function:

function(x, w = NULL){...}

nested_transmute() and nested_transmute2() similarly return a function:

function(x, w1 = NULL, w2 = NULL){...}

Details

The function transmute_weights(r, s) returns a function to compute a vector of weights v(x, w) such that

generalized_mean(r)(x, w) == generalized_mean(s)(x, v(x, w))

nested_transmute(r1, r2, t, s) and nested_transmute2(r1, r2, t, s) do the same for nested generalized means, so that

nested_mean(r1, r2, t)(x, w1, w2) ==
  generalized_mean(s)(x, v(x, w1, w2))

This generalizes the result for turning a geometric mean into an arithmetic mean (and vice versa) in section 4.2 of Balk (2008), and a Fisher mean into an arithmetic mean in section 6 of Reinsdorf et al. (2002), although these are usually the most important cases. See Martin (2021) for details. nested_transmute2() takes a slightly different approach than nested_transmute(), generalizing the van IJzeren arithmetic decomposition for the Fisher index (Balk, 2008, section 4.2.2) using the approach by Martin (2021), although in most cases the results are broadly similar.

Transmuting weights returns a value that is the same length as x, so any missing values in x or the weights will return NA. Unless all values are NA, however, the result for will still satisfy the above identities when na.rm = TRUE.

References

Balk, B. M. (2008). Price and Quantity Index Numbers. Cambridge University Press.

Martin, S. (2021). A note on general decompositions for price indexes. Prices Analytical Series, Statistics Canada catalogue no. 62F0014M. Statistics Canada, Ottawa.

Reinsdorf, M. B., Diewert, W. E., and Ehemann, C. (2002). Additive decompositions for Fisher, Törnqvist and geometric mean indexes. Journal of Economic and Social Measurement, 28(1-2):51–61.

Sydsaeter, K., Strom, A., and Berck, P. (2005). Economists' Mathematical Manual (4th edition). Springer.

See also

generalized_mean() for the generalized mean and nested_mean() for the nested mean.

extended_mean() for the extended mean that underlies transmute_weights().

contributions() for calculating additive percent-change contributions.

grouped() to make these functions operate on grouped data.

Other weights functions: factor_weights(), scale_weights()

Examples

x <- 1:3
y <- 4:6
w <- 3:1

#---- Transforming generalized means ----

# Calculate the geometric mean as an arithmetic mean and
# harmonic mean by transmuting the weights

geometric_mean(x)
#> [1] 1.817121
arithmetic_mean(x, transmute_weights(0, 1)(x))
#> [1] 1.817121
harmonic_mean(x, transmute_weights(0, -1)(x))
#> [1] 1.817121

# Transmuting the weights for a harmonic mean into those
# for an arithmetic mean is the same as using weights w / x

all.equal(transmute_weights(-1, 1)(x, w), scale_weights(w / x))
#> [1] TRUE

# Transmuting the weights for an arithmetic mean into those
# for a harmonic mean is the same as using weights w * x

all.equal(transmute_weights(1, -1)(x, w), scale_weights(w * x))
#> [1] TRUE

# Works for nested means, too

w1 <- 3:1
w2 <- 1:3

fisher_mean(x, w1, w2)
#> [1] 1.825742

arithmetic_mean(x, nested_transmute(0, c(1, -1), 1)(x, w1, w2))
#> [1] 1.825742
arithmetic_mean(x, nested_transmute2(0, c(1, -1), 1)(x, w1, w2))
#> [1] 1.825742

# Note that nested_transmute() has an invariance property
# not shared by nested_transmute2()

all.equal(
  nested_transmute(0, c(1, -1), 1)(x, w1, w2),
  transmute_weights(2, 1)(
    x, nested_transmute(0, c(1, -1), 2)(x, w1, w2)
  )
)
#> [1] TRUE

all.equal(
  nested_transmute2(0, c(1, -1), 1)(x, w1, w2),
  transmute_weights(2, 1)(
    x, nested_transmute2(0, c(1, -1), 2)(x, w1, w2)
  )
)
#> [1] "Mean relative difference: 0.0015427"

#---- Monotonicity ----

# Transmuted weights increase when x is small and decrease
# when x is large if r < s

transmute_weights(0, 1)(x, w) > scale_weights(w)
#> [1]  TRUE FALSE FALSE

# The opposite happens when r > s

transmute_weights(1, 0)(x, w) > scale_weights(w)
#> [1] FALSE  TRUE  TRUE

#---- Percent-change contributions ----

# Transmuted weights can be used to calculate percent-change
# contributions for, e.g., a geometric price index

transmute_weights(0, 1)(x) * (x - 1)
#> [1] 0.0000000 0.3122793 0.5048413
geometric_contributions(x) # the more convenient way
#> [1] 0.0000000 0.3122793 0.5048413

#---- Basket representation of a price index ----

# Any generalized-mean index can be represented as a basket-style
# index by transmuting the weights, which is how some authors
# define a price index (e.g., Sydsaeter et al., 2005, p. 174)

p1 <- 2:6
p0 <- 1:5

qs <- transmute_weights(-1, 1)(p1 / p0) / p0
all.equal(harmonic_mean(p1 / p0), sum(p1 * qs) / sum(p0 * qs))
#> [1] TRUE