p0 <- price6[[2]]
p1 <- price6[[3]]
q0 <- quantity6[[2]]
q1 <- quantity6[[3]]
pb <- price6[[1]]
qb <- quantity6[[1]]
#---- Calculating price indexes ----
# Most indexes can be calculated by combining the appropriate weights
# with the correct type of mean
geometric_index("Laspeyres")(p1, p0, q0)
geometric_mean(p1 / p0, index_weights("Laspeyres")(p0, q0))
# Arithmetic Laspeyres index
laspeyres_index(p1, p0, q0)
arithmetic_mean(p1 / p0, index_weights("Laspeyres")(p0, q0))
# Harmonic calculation for the arithmetic Laspeyres
harmonic_mean(p1 / p0, index_weights("HybridLaspeyres")(p1, q0))
# Same as transmuting the weights
all.equal(
scale_weights(index_weights("HybridLaspeyres")(p1, q0)),
transmute_weights(1, -1)(p1 / p0, index_weights("Laspeyres")(p0, q0))
)
# This strategy can be used to make more exotic indexes, like the
# quadratic-mean index (von der Lippe, 2007, p. 61)
generalized_mean(2)(p1 / p0, index_weights("Laspeyres")(p0, q0))
# Or the exponential mean index (p. 62)
log(arithmetic_mean(exp(p1 / p0), index_weights("Laspeyres")(p0, q0)))
# Or the arithmetic hybrid index (von der Lippe, 2015, p. 5)
arithmetic_mean(p1 / p0, index_weights("HybridLaspeyres")(p1, q0))
contraharmonic_mean(p1 / p0, index_weights("Laspeyres")(p0, q0))
# Unlike its arithmetic counterpart, the geometric Laspeyres can
# increase when base-period prices increase if some of these prices
# are small
gl <- geometric_index("Laspeyres")
p0_small <- replace(p0, 1, p0[1] / 5)
p0_dx <- replace(p0_small, 1, p0_small[1] + 0.01)
gl(p1, p0_small, q0) < gl(p1, p0_dx, q0)
#---- Price updating the weights in a price index ----
# Chain an index by price updating the weights
p2 <- price6[[4]]
laspeyres_index(p2, p0, q0)
I1 <- laspeyres_index(p1, p0, q0)
w_pu <- update_weights(p1 / p0, index_weights("Laspeyres")(p0, q0))
I2 <- arithmetic_mean(p2 / p1, w_pu)
I1 * I2
# Works for other types of indexes, too
harmonic_index("Laspeyres")(p2, p0, q0)
I1 <- harmonic_index("Laspeyres")(p1, p0, q0)
w_pu <- factor_weights(-1)(p1 / p0, index_weights("Laspeyres")(p0, q0))
I2 <- harmonic_mean(p2 / p1, w_pu)
I1 * I2
#---- Percent-change contributions ----
# Percent-change contributions for the Tornqvist index
w <- index_weights("Tornqvist")(p1, p0, q1, q0)
(con <- geometric_contributions(p1 / p0, w))
all.equal(sum(con), geometric_index("Tornqvist")(p1, p0, q1, q0) - 1)
#---- Missing values ----
# NAs get special treatment
p_na <- replace(p0, 6, NA)
# Drops the last price relative
laspeyres_index(p1, p_na, q0, na.rm = TRUE)
# Only drops the last period-0 price
sum(p1 * q0, na.rm = TRUE) / sum(p_na * q0, na.rm = TRUE)
#---- von Bortkiewicz decomposition ----
paasche_index(p1, p0, q1) / laspeyres_index(p1, p0, q0) - 1
wl <- scale_weights(index_weights("Laspeyres")(p0, q0))
pl <- laspeyres_index(p1, p0, q0)
ql <- quantity_index(laspeyres_index)(q1, q0, p0)
sum(wl * (p1 / p0 / pl - 1) * (q1 / q0 / ql - 1))
# Similar decomposition for geometric Laspeyres/Paasche
wp <- scale_weights(index_weights("Paasche")(p1, q1))
gl <- geometric_index("Laspeyres")(p1, p0, q0)
gp <- geometric_index("Paasche")(p1, p0, q1)
log(gp / gl)
sum(scale_weights(wl) * (wp / wl - 1) * log(p1 / p0 / gl))
#---- Consistency in aggregation ----
p0a <- p0[1:3]
p0b <- p0[4:6]
p1a <- p1[1:3]
p1b <- p1[4:6]
q0a <- q0[1:3]
q0b <- q0[4:6]
q1a <- q1[1:3]
q1b <- q1[4:6]
# Indexes based on the generalized mean with value share weights are
# consistent in aggregation
lm_index(0.75)(p1, p0, q0)
w <- index_weights("LloydMoulton")(p0, q0)
Ia <- generalized_mean(0.25)(p1a / p0a, w[1:3])
Ib <- generalized_mean(0.25)(p1b / p0b, w[4:6])
generalized_mean(0.25)(c(Ia, Ib), c(sum(w[1:3]), sum(w[4:6])))
# Agrees with group-wise indexes
all.equal(lm_index(0.75)(p1a, p0a, q0a), Ia)
all.equal(lm_index(0.75)(p1b, p0b, q0b), Ib)
# Care is needed with more complex weights, e.g., Drobisch, as this
# doesn't fit Balk's (2008) definition (p. 113) of a generalized-mean
# index (it's the arithmetic mean of a Laspeyres and Paasche index)
arithmetic_index("Drobisch")(p1, p0, q1, q0)
w <- index_weights("Drobisch")(p1, p0, q1, q0)
Ia <- arithmetic_mean(p1a / p0a, w[1:3])
Ib <- arithmetic_mean(p1b / p0b, w[4:6])
arithmetic_mean(c(Ia, Ib), c(sum(w[1:3]), sum(w[4:6])))
# Does not agree with group-wise indexes
all.equal(arithmetic_index("Drobisch")(p1a, p0a, q1a, q0a), Ia)
all.equal(arithmetic_index("Drobisch")(p1b, p0b, q1b, q0b), Ib)
Run the code above in your browser using DataLab