Hierarchical time series are time series that can be divided into sub-series. In persephone, such objects are created similar to a nested list. The following example creates a series with European aggregate based on another aggregate of south and north European countries or their IPI respectively.

First we load the data from the RJDemetra and remove the EU aggregate.

library(persephone)
data(ipi_c_eu, package = "RJDemetra")
ipi_eu <- ipi_c_eu[, -c(28:34)]

For all countries’ time series we now want to generate a persephone object with Tramo as method.

ts_28 <- lapply(ipi_eu, perTramo)

We generate a additional layer based on a certain regional grouping of the countries

south_eastern_europe <- c("BG","EL","CY","RO")
northern_europe <- c("DK","FI","SE")
central_europe <- c("HR","DE","CZ","SK","HU","AT","SI","LU","EE","LT","LV","PL")
southern_europe <- c("IT","ES","PT","MT")
western_europe <- c("FR","BE","NL","UK") # without IE (missing from the dataset)

The list argument can be used to create a hierachical persephone object based on a list of persephone objects.

hts_see <- perHts(list = ts_28[south_eastern_europe])
hts_ne <- perHts(list = ts_28[northern_europe])
hts_ce <- perHts(list = ts_28[central_europe])
hts_se <- perHts(list = ts_28[southern_europe])
hts_we <- perHts(list = ts_28[western_europe])

An additional layer is only the nothern part and southern part

hts_np <- perHts(norhtern_europe = hts_ne,
                 western_europe = hts_we,
                 central_europe = hts_ce
)
hts_sp <- perHts(southern_europe = hts_se,
                 south_eastern_europe = hts_see
)

Finally we aggregate them to the whole of EU.

ht_europe <- perHts(north_part = hts_np,
                 south_part = hts_sp
)
ht_europe
#>  component                          run   class                 
#>                                     FALSE hierarchicalTimeSeries
#>  north_part                         FALSE hierarchicalTimeSeries
#>  north_part/norhtern_europe         FALSE hierarchicalTimeSeries
#>  north_part/norhtern_europe/DK      FALSE tramoseatsSingle      
#>  north_part/norhtern_europe/FI      FALSE tramoseatsSingle      
#>  north_part/norhtern_europe/SE      FALSE tramoseatsSingle      
#>  north_part/western_europe          FALSE hierarchicalTimeSeries
#>  north_part/western_europe/FR       FALSE tramoseatsSingle      
#>  north_part/western_europe/BE       FALSE tramoseatsSingle      
#>  north_part/western_europe/NL       FALSE tramoseatsSingle      
#>  north_part/western_europe/UK       FALSE tramoseatsSingle      
#>  north_part/central_europe          FALSE hierarchicalTimeSeries
#>  north_part/central_europe/HR       FALSE tramoseatsSingle      
#>  north_part/central_europe/DE       FALSE tramoseatsSingle      
#>  north_part/central_europe/CZ       FALSE tramoseatsSingle      
#>  north_part/central_europe/SK       FALSE tramoseatsSingle      
#>  north_part/central_europe/HU       FALSE tramoseatsSingle      
#>  north_part/central_europe/AT       FALSE tramoseatsSingle      
#>  north_part/central_europe/SI       FALSE tramoseatsSingle      
#>  north_part/central_europe/LU       FALSE tramoseatsSingle      
#>  north_part/central_europe/EE       FALSE tramoseatsSingle      
#>  north_part/central_europe/LT       FALSE tramoseatsSingle      
#>  north_part/central_europe/LV       FALSE tramoseatsSingle      
#>  north_part/central_europe/PL       FALSE tramoseatsSingle      
#>  south_part                         FALSE hierarchicalTimeSeries
#>  south_part/southern_europe         FALSE hierarchicalTimeSeries
#>  south_part/southern_europe/IT      FALSE tramoseatsSingle      
#>  south_part/southern_europe/ES      FALSE tramoseatsSingle      
#>  south_part/southern_europe/PT      FALSE tramoseatsSingle      
#>  south_part/southern_europe/MT      FALSE tramoseatsSingle      
#>  south_part/south_eastern_europe    FALSE hierarchicalTimeSeries
#>  south_part/south_eastern_europe/BG FALSE tramoseatsSingle      
#>  south_part/south_eastern_europe/EL FALSE tramoseatsSingle      
#>  south_part/south_eastern_europe/CY FALSE tramoseatsSingle      
#>  south_part/south_eastern_europe/RO FALSE tramoseatsSingle

Now we make the first run:

ht_europe$run()
ht_europe
#>  component                          run  class                  seasonality
#>                                     TRUE hierarchicalTimeSeries Present    
#>  north_part                         TRUE hierarchicalTimeSeries Present    
#>  north_part/norhtern_europe         TRUE hierarchicalTimeSeries Present    
#>  north_part/norhtern_europe/DK      TRUE tramoseatsSingle       Present    
#>  north_part/norhtern_europe/FI      TRUE tramoseatsSingle       Present    
#>  north_part/norhtern_europe/SE      TRUE tramoseatsSingle       Present    
#>  north_part/western_europe          TRUE hierarchicalTimeSeries Present    
#>  north_part/western_europe/FR       TRUE tramoseatsSingle       Present    
#>  north_part/western_europe/BE       TRUE tramoseatsSingle       Present    
#>  north_part/western_europe/NL       TRUE tramoseatsSingle       Present    
#>  north_part/western_europe/UK       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe          TRUE hierarchicalTimeSeries Present    
#>  north_part/central_europe/HR       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/DE       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/CZ       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/SK       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/HU       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/AT       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/SI       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/LU       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/EE       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/LT       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/LV       TRUE tramoseatsSingle       Present    
#>  north_part/central_europe/PL       TRUE tramoseatsSingle       Present    
#>  south_part                         TRUE hierarchicalTimeSeries Present    
#>  south_part/southern_europe         TRUE hierarchicalTimeSeries Present    
#>  south_part/southern_europe/IT      TRUE tramoseatsSingle       Present    
#>  south_part/southern_europe/ES      TRUE tramoseatsSingle       Present    
#>  south_part/southern_europe/PT      TRUE tramoseatsSingle       Present    
#>  south_part/southern_europe/MT      TRUE tramoseatsSingle       Present    
#>  south_part/south_eastern_europe    TRUE hierarchicalTimeSeries Present    
#>  south_part/south_eastern_europe/BG TRUE tramoseatsSingle       Present    
#>  south_part/south_eastern_europe/EL TRUE tramoseatsSingle       Present    
#>  south_part/south_eastern_europe/CY TRUE tramoseatsSingle       Present    
#>  south_part/south_eastern_europe/RO TRUE tramoseatsSingle       Present    
#>  logTransform arimaMdl       nOutliers qStat
#>   TRUE        (2 1 1)(0 1 1) 6         NA   
#>   TRUE        (0 1 1)(0 1 1) 8         NA   
#>   TRUE        (0 1 1)(0 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 1         NA   
#>   TRUE        (2 1 0)(1 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 6         NA   
#>  FALSE        (2 1 0)(0 1 1) 4         NA   
#>   TRUE        (0 1 1)(0 1 1) 3         NA   
#>   TRUE        (2 1 0)(1 1 1) 2         NA   
#>  FALSE        (3 0 0)(0 1 1) 4         NA   
#>   TRUE        (2 1 0)(0 1 1) 5         NA   
#>   TRUE        (0 1 1)(0 1 1) 5         NA   
#>   TRUE        (2 1 0)(0 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 4         NA   
#>   TRUE        (0 1 1)(0 1 1) 7         NA   
#>   TRUE        (0 1 1)(0 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 5         NA   
#>   TRUE        (3 1 1)(0 1 1) 4         NA   
#>  FALSE        (0 1 1)(0 1 1) 4         NA   
#>   TRUE        (3 1 1)(0 1 1) 1         NA   
#>  FALSE        (0 1 1)(0 1 1) 1         NA   
#>   TRUE        (3 1 1)(0 1 1) 1         NA   
#>   TRUE        (0 1 1)(0 1 1) 3         NA   
#>   TRUE        (0 1 1)(0 1 1) 3         NA   
#>   TRUE        (2 1 0)(0 1 1) 3         NA   
#>  FALSE        (2 1 0)(0 1 1) 7         NA   
#>   TRUE        (0 1 1)(0 1 1) 4         NA   
#>   TRUE        (0 1 1)(0 1 1) 5         NA   
#>   TRUE        (2 1 0)(0 1 1) 0         NA   
#>   TRUE        (0 1 1)(0 1 1) 4         NA   
#>   TRUE        (0 1 1)(0 1 1) 6         NA   
#>   TRUE        (0 1 1)(0 1 1) 1         NA   
#>   TRUE        (0 1 1)(0 1 1) 2         NA   
#>   TRUE        (0 1 1)(0 1 1) 4         NA

Weights

Weights can be used to customize the aggregation step, so the hierachical time series is not just the sum of its components, but the weighted sum. This can be especially helpful if the timeseries are indices.

Time-invariant weights

The weights parameter will be set as numeric vector with length equal to the number of components.

Almost the same call, but with weights, one for each component and one for all time points.

hts_see <- perHts(list = ts_28[south_eastern_europe], weights=c(1,2,3,4))
hts_ne <- perHts(list = ts_28[northern_europe], weights = c(5,6,7))
hts_ce <- perHts(list = ts_28[central_europe], weights = rep(1,12))
hts_se <- perHts(list = ts_28[southern_europe], weights = c(8,9,10,10.5))
hts_we <- perHts(list = ts_28[western_europe], weights = c(11,12,13,14)) # without IE

In additional aggregation steps, the weight is automatically summed up. So e.g. the weight for central europe is 12, the sum of 12 times 1.

hts_np <- perHts(northern_europe = hts_ne,
                 western_europe = hts_we,
                 central_europe = hts_ce
)
hts_sp <- perHts(southern_europe = hts_se,
                 south_eastern_europe = hts_see
)
knitr::kable(head(hts_np$weights))
northern_europe western_europe central_europe
18 50 12
18 50 12
18 50 12
18 50 12
18 50 12
18 50 12
ht_europe <- perHts(north_part = hts_np,
                 south_part = hts_sp
)

knitr::kable(head(ht_europe$weights))
north_part south_part
80 47.5
80 47.5
80 47.5
80 47.5
80 47.5
80 47.5

Time-variant weights

In many scenarios weights are not fixed over time, but change, e.g. if the turnover is used to aggregate a certain production index. In these scenarios weights can be provided as lists of time series or as a mts object.

We are starting with weights equal to 1 and then only change the weight of Austria over time.

weights_eu <- ipi_eu * 0 + 1
weights_eu[is.na(weights_eu)] <- 1
weights_eu[,"AT"] <- weights_eu[,"AT"]+rlnorm(weights_eu[,"AT"])

We can now call the perHts function with the mts as input.

hts_see <- perHts(list = ts_28[south_eastern_europe],
                   weights=weights_eu[,south_eastern_europe])
hts_ne <- perHts(list = ts_28[northern_europe],
                  weights=weights_eu[,northern_europe])
hts_ce <- perHts(list = ts_28[central_europe],
                  weights=weights_eu[,central_europe])
hts_se <- perHts(list = ts_28[southern_europe],
                  weights=weights_eu[,southern_europe])
hts_we <- perHts(list = ts_28[western_europe],
                  weights=weights_eu[,western_europe])

And then we can proceed as before.

hts_np <- perHts(northern_europe = hts_ne,
                 western_europe = hts_we,
                 central_europe = hts_ce
)
hts_sp <- perHts(southern_europe = hts_se,
                 south_eastern_europe = hts_see
)
knitr::kable(head(hts_np$weights))
northern_europe western_europe central_europe
3 4 17.83245
3 4 12.53093
3 4 19.16617
3 4 12.74882
3 4 14.68639
3 4 13.51903
ht_europe <- perHts(north_part = hts_np,
                 south_part = hts_sp
)

knitr::kable(head(ht_europe$weights))
north_part south_part
24.83245 8
19.53093 8
26.16617 8
19.74882 8
21.68639 8
20.51903 8