---
title: "Aggregating across dimensions"
vignette: >
  %\VignetteIndexEntry{Aggregating across dimensions}
  %\VignetteEngine{litedown::vignette}
  %\VignetteEncoding{UTF-8}
---

```{r}
#| echo: false
litedown::reactor(print = NA)
```

Price indexes are often aggregated over multiple hierarchical dimensions.
Industry indexes that use, say, sequential Poisson sampling to draw a sample of
businesses are a good example, as there are usually take-all and
take-some strata in addition to, say, an industry classification. An industry-based
index can also form the basis for a product-based index, or vice versa.
In both cases, an index is re-aggregated to produce indexes for new dimensions
that aren't part of the original aggregation structure.

## Interacting hierarchical classifications

Let's extend `vignette("piar")` by adding another dimension to the
classification to say if a business belongs to the take-all or take-some
sampling stratum.

```{r}
library(piar)

elementals <- ms_prices |>
  transform(
    relative = price_relative(price, period = period, product = product)
  ) |>
  elementary_index(relative ~ period + business, na.rm = TRUE)
```

```{r}
ms_weights$stratum <- c("TS", "TA", "TS", "TS", "TS")

ms_weights
```

The easiest way to deal with multiple digit-wise classifications is to
concatenate them into one classification with the `combine_classifications()`
function. In this example the "stratum"
dimension comes before the "classification" dimension for the purposes
of overall-mean imputation.

```{r}
classification_sps <- combine_classifications(
  expand_classification(ms_weights$classification),
  list(ms_weights$stratum)
)

pias_sps <- aggregation_structure(
  c(classification_sps, list(ms_weights$business)),
  ms_weights$weight
)

pias_sps
```

The elementary indexes can now be aggregated according to this new
aggregation structure.

```{r}
index_sps <- aggregate(elementals, pias_sps, na.rm = TRUE)

index_sps
```

When a price index has many dimensions (e.g., industry, sampling
stratum, region), it can be useful to interact the classifications for
these different dimensions to get all possible aggregation structures.
The aggregated index can then be re-aggregated to get index values for
all dimensions.

Continuing with the example, the industry and strata classifications can
be interacted to get two aggregation structures that can be used to
re-aggregate `index_sps`.

```{r}
interacted_hierarchy <- interact_classifications(
  expand_classification(ms_weights$classification),
  expand_classification(ms_weights$stratum)
)

pias_sps2 <- lapply(
  interacted_hierarchy,
  \(x) aggregation_structure(c(x, list(ms_weights$business)), ms_weights$weight)
)

index_sps2 <- lapply(pias_sps2, \(x) {
  aggregate(index_sps, x, include_ea = FALSE)
})
```

The resulting indexes can be merged together to give an index that
includes all combinations of industry and sampling stratum.

```{r}
Reduce(merge, index_sps2)
```

## Aggregating over separate classifications

Rather aggregating over multiple dimensions within a combined hierarchical classification,
in some cases an index is re-aggregated over a different classification by means of
a concordance between the elementary aggregates. Continuing with the previous example,
suppose industry `11` produce products `a` and `b`, and industry `12` produce products `b` and `c`, with the following weights.

```{r}
product_weights <- data.frame(
  product = c("a", "b", "b", "c"),
  industry = c("11", "11", "12", "12"),
  weight = 1:4
)

product_pias <- aggregation_structure(
  combine_classifications(
    list(product_weights$product),
    list(product_weights$industry)
  ),
  product_weights$weight
)

product_pias
```

The industry-based index can be expanded and re-aggregated to make a product-based
index. The key to doing so is to construct a concordance between industries and products.

```{r}
concord <- setNames(product_weights$industry, levels(product_pias)$ea)
concord
```

This concordance can be used to expand the industry index and re-aggregate it with the
product-based aggregation structure.

```{r}
aggregate(index_sps[concord], product_pias)
```
