Contributions

Product contributions

It’s often convenient to decompose an index into the (additive) contribution of each price relative, also known as the percent-change contribution. This can be done with the same work flow used in vignette("piar"), specifying contrib = TRUE when calling elementary_index(). (See vignette("decomposing-indexes") for the underlying theory.)

library(piar)

# Make an aggregation structure.
ms_weights[c("level1", "level2")] <-
  expand_classification(ms_weights$classification)

pias <- ms_weights[c("level1", "level2", "business", "weight")] |>
  as_aggregation_structure()

# Make elementary index with contributions.
elementals <- ms_prices |>
  transform(
    relative = price_relative(price, period = period, product = product)
  ) |>
  elementary_index(
    relative ~ period + business,
    product = product,
    na.rm = TRUE,
    contrib = TRUE
  )

As with index values, percent-change contributions for a given level of the index can be extracted as a matrix.

contrib(elementals, level = "B1")
202001 202002 202003 202004
0.000 0.000 0.000 0.000
-0.666 0.000
0.000 -0.105

Or as a data frame.

contrib2DF(elementals, level = "B1")
period level product value
202001 B1 1 0.000
202001 B1 2
202001 B1 3 0.000
202002 B1 2
202002 B1 3 -0.105
202003 B1 2 -0.666
202003 B1 3
202004 B1 3

Aggregating the elementary indexes automatically aggregates percent-change contributions, so no extra steps are needed after the elementary indexes are made.

index <- aggregate(elementals, pias, na.rm = TRUE)

contrib(index)
202001 202002 202003 202004
0.000 0.000 0.000 0.000
0.000 -0.088 0.273 -0.078
0.000 0.000 0.059
0.000 0.000 1.323
-0.293 0.000
0.000 0.095
0.000 0.428
0.000 0.516 -0.205 -0.011
0.000 0.019 0.176 -0.004
0.000 -0.080 0.113 -0.059

Index contributions

After an index has been calculated, it’s often useful to compute the contribution of higher-level indexes towards the total index. The easiest way to do this with a collection of pre-computed index values is to simply coerce them into an index object with the index values as contributions and reaggregate with a restricted aggregation structure.

index <- as_index(as.matrix(index), contrib = TRUE)

If the index values are already an index object, it’s also possible to directly replace the contributions with the set_contrib_from_index() function. We can now cut the aggregation structure to keep only the top two levels and reaggregate to get the contribution of the second-level indexes to the top level index.

set_contrib_from_index(index) |>
  aggregate(cut(pias, 2)) |>
  contrib()
202001 202002 202003 202004
0.000 0.184 0.039 0.352
0.000 0.116 0.024 1.382

The same approach works with a fixed-base index as well.

chain(index) |>
  set_contrib_from_index() |>
  aggregate(cut(pias, 2)) |>
  contrib()
202001 202002 202003 202004
0.000 0.184 0.235 0.722
0.000 0.116 0.148 2.059