tsraking_driver {gseries} | R Documentation |
Helper function for tsraking()
Description
(version française: https://StatCan.github.io/gensol-gseries/fr/reference/tsraking_driver.html)
Helper function for the tsraking()
function that conveniently determines the required set of raking
problems to be solved and internally generates the individual calls to tsraking()
. It is especially
useful in the context of temporal total (e.g., annual total) preservation where each individual raking
problem either involves a single period for incomplete temporal groups (e.g., incomplete years) or several
periods for complete temporal groups (e.g., the set of periods of a complete year).
Usage
tsraking_driver(
in_ts,
..., # `tsraking()` arguments excluding `data_df`
temporal_grp_periodicity = 1,
temporal_grp_start = 1
)
Arguments
in_ts |
(mandatory) Time series (object of class "ts" or "mts") that contains the time series data to be reconciled. They are the raking problems' input data (initial solutions). | |||||||
... |
Arguments passed on to
| |||||||
temporal_grp_periodicity |
(optional) Positive integer defining the number of periods in temporal groups for which the totals should be preserved.
E.g., specify Default value is | |||||||
temporal_grp_start |
(optional) Integer in the [1 .. Default value is |
Details
This function solves one raking problem with tsraking()
per processing group (see section Processing groups for
details). The mathematical expression of these raking problem can be found in the Details section of the tsraking()
documentation.
The alterability coefficients data frame (argument alterability_df
) specified with tsraking_driver()
can either
contain:
A single observation: the specified coefficients will be used for all periods of input time series object (argument
in_ts
).A number of observations equal to
frequency(in_ts)
: the specified coefficients will be used for the corresponding cycle of the input time series object (argumentin_ts
) periods. Monthly data example: 1st observation for January, 2nd observation for February, etc.).A number of observations equal to
nrow(in_ts)
: the specified coefficients will be used for the corresponding periods of the input time series object (argumentin_ts
), i.e., 1st observation for the 1st period, 2nd observation for the 2nd period, etc.).
Specifying quiet = TRUE
will suppress the tsraking()
messages (e.g., function header) and only
display essential information such as warnings, errors and the period (or set of periods) being reconciled.
We advise against wrapping your tsraking_driver()
function call with suppressMessages()
to further
suppress the display of the raking period(s) information as this would make troubleshooting difficult
in case of issues with individual raking problems.
Although tsraking()
could be called with *apply()
to successively reconcile all the periods of the input time
series (in_ts
), using tsraking_driver()
has a few advantages, namely:
temporal total preservation (only period-by-period processing, without temporal total preservation, would be possible with
*apply()
);more flexibility in the specification of user-defined alterability coefficients (e.g., period-specific values);
display of the period being processed (reconciled) in the console, which is useful for troubleshooting individual raking problems;
improved error handling, i.e., better management of warnings or errors if they were to occur only for some raking problems (periods);
readily returns a "ts" ("mts") object.
Value
The function returns a time series object (class "ts" or "mts") containing the reconciled component series,
reconciled cross-sectional control totals and other series specified with tsraking()
argument id
. It can be
explicitly coerced to another type of object with the appropriate as*()
function (e.g., tsibble::as_tsibble()
would coerce it to a tsibble).
Note that a NULL
object is returned if an error occurs before data processing could start. Otherwise, if execution
gets far enough so that data processing could start, then an incomplete object (with NA
values) would be returned
in case of errors.
Processing groups
The set of periods of a given reconciliation (raking or balancing) problem is called a processing group and either corresponds to:
a single period with period-by-period processing or, when preserving temporal totals, for the individual periods of an incomplete temporal group (e.g., an incomplete year)
or the set of periods of a complete temporal group (e.g., a complete year) when preserving temporal totals.
The total number of processing groups (total number of reconciliation problems) depends on the set of
periods in the input time series object (argument in_ts
) and on the value of arguments
temporal_grp_periodicity
and temporal_grp_start
.
Common scenarios include temporal_grp_periodicity = 1
(default) for period-by period processing without
temporal total preservation and temporal_grp_periodicity = frequency(in_ts)
for the preservation of annual
totals (calendar years by default). Argument temporal_grp_start
allows the specification of other types of
(non-calendar) years. E.g., fiscal years starting on April correspond to temporal_grp_start = 4
with monthly
data and temporal_grp_start = 2
with quarterly data. Preserving quarterly totals with monthly data would
correspond to temporal_grp_periodicity = 3
.
By default, temporal groups covering more than a year (i.e., corresponding to temporal_grp_periodicity > frequency(in_ts)
start on a
year that is a multiple of
ceiling(temporal_grp_periodicity / frequency(in_ts))
. E.g., biennial groups corresponding to temporal_grp_periodicity = 2 * frequency(in_ts)
start on an even year by default. This behaviour can be changed with argument temporal_grp_start
. E.g., the
preservation of biennial totals starting on an odd year instead of an even year (default) corresponds to
temporal_grp_start = frequency(in_ts) + 1
(along with temporal_grp_periodicity = 2 * frequency(in_ts)
).
See the gs.build_proc_grps()
Examples for common processing group scenarios.
References
Statistics Canada (2018). "Chapter 6: Advanced topics", Theory and Application of Reconciliation (Course code 0437), Statistics Canada, Ottawa, Canada.
See Also
tsraking()
tsbalancing()
rkMeta_to_blSpecs()
gs.build_proc_grps()
Examples
# 1-dimensional raking problem where the quarterly sales of cars in the 3 prairie
# provinces (Alb., Sask. and Man.) for 8 quarters, from 2019 Q2 to 2021 Q1, must
# sum up to the total (`cars_tot`).
# Problem metadata
my_metadata <- data.frame(series = c("cars_alb", "cars_sask", "cars_man"),
total1 = rep("cars_tot", 3))
my_metadata
# Problem data
my_series <- ts(matrix(c(14, 18, 14, 58,
17, 14, 16, 44,
14, 19, 18, 58,
20, 18, 12, 53,
16, 16, 19, 44,
14, 15, 16, 50,
19, 20, 14, 52,
16, 15, 19, 51),
ncol = 4,
byrow = TRUE,
dimnames = list(NULL, c("cars_alb", "cars_sask",
"cars_man", "cars_tot"))),
start = c(2019, 2),
frequency = 4)
###########
# Example 1: Period-by-period processing without temporal total preservation.
# Reconcile the data
out_raked1 <- tsraking_driver(my_series, my_metadata)
# Initial data
my_series
# Reconciled data
out_raked1
# Check the output cross-sectional constraint
all.equal(rowSums(out_raked1[, my_metadata$series]), as.vector(out_raked1[, "cars_tot"]))
# Check the control total (fixed)
all.equal(my_series[, "cars_tot"], out_raked1[, "cars_tot"])
###########
# Example 2: Annual total preservation for year 2020 (period-by-period processing
# for incomplete years 2019 and 2021), with `quiet = TRUE` to avoid
# displaying the function header for all processing groups.
# First, check that the 2020 annual total for the total series (`cars_tot`) and the
# sum of the component series (`cars_alb`, `cars_sask` and `cars_man`) matches.
# Otherwise, this "grand total" discrepancy would first have to be resolved before
# calling `tsraking_driver()`.
tot2020 <- aggregate.ts(window(my_series, start = c(2020, 1), end = c(2020, 4)))
all.equal(as.numeric(tot2020[, "cars_tot"]), sum(tot2020[, my_metadata$series]))
# Reconcile the data
out_raked2 <- tsraking_driver(in_ts = my_series,
metadata_df = my_metadata,
quiet = TRUE,
temporal_grp_periodicity = frequency(my_series))
# Initial data
my_series
# Reconciled data
out_raked2
# Check the output cross-sectional constraint
all.equal(rowSums(out_raked2[, my_metadata$series]), as.vector(out_raked2[, "cars_tot"]))
# Check the output temporal constraints (2020 annual totals for each series)
all.equal(tot2020,
aggregate.ts(window(out_raked2, start = c(2020, 1), end = c(2020, 4))))
# Check the control total (fixed)
all.equal(my_series[, "cars_tot"], out_raked2[, "cars_tot"])
###########
# Example 3: Annual total preservation for fiscal years defined from April to March
# (2019Q2-2020Q1 and 2020Q2-2021Q1).
# Calculate the fiscal year totals (as an annual "ts" object)
fiscalYr_tot <- ts(rbind(aggregate.ts(window(my_series,
start = c(2019, 2),
end = c(2020, 1))),
aggregate.ts(window(my_series,
start = c(2020, 2),
end = c(2021, 1)))),
start = 2019,
frequency = 1)
# Discrepancies in both fiscal year totals (total series vs. sum of the component series)
as.numeric(fiscalYr_tot[, "cars_tot"]) - rowSums(fiscalYr_tot[, my_metadata$series])
# 3a) Reconcile the fiscal year totals (rake the fiscal year totals of the component series
# to those of the total series).
new_fiscalYr_tot <- tsraking_driver(in_ts = fiscalYr_tot,
metadata_df = my_metadata,
quiet = TRUE)
# Confirm that the previous discrepancies are now "gone" (are both zero)
as.numeric(new_fiscalYr_tot[, "cars_tot"]) - rowSums(new_fiscalYr_tot[, my_metadata$series])
# 3b) Benchmark the quarterly component series to these new (coherent) fiscal year totals.
out_bench <- benchmarking(series_df = ts_to_tsDF(my_series[, my_metadata$series]),
benchmarks_df = ts_to_bmkDF(
new_fiscalYr_tot[, my_metadata$series],
ind_frequency = frequency(my_series),
# Fiscal years starting on Q2 (April)
bmk_interval_start = 2),
rho = 0.729,
lambda = 1,
biasOption = 2,
allCols = TRUE,
quiet = TRUE)
my_new_ser <- tsDF_to_ts(cbind(out_bench$series, cars_tot = my_series[, "cars_tot"]),
frequency = frequency(my_series))
# 3c) Reconcile the quarterly data with preservation of fiscal year totals.
out_raked3 <- tsraking_driver(in_ts = my_new_ser,
metadata_df = my_metadata,
temporal_grp_periodicity = frequency(my_series),
# Fiscal years starting on Q2 (April)
temporal_grp_start = 2,
quiet = TRUE)
# Initial data
my_series
# With coherent fiscal year totals
my_new_ser
# Reconciled data
out_raked3
# Check the output cross-sectional constraint
all.equal(rowSums(out_raked3[, my_metadata$series]), as.vector(out_raked3[, "cars_tot"]))
# Check the output temporal constraints (both fiscal year totals for all series)
all.equal(rbind(aggregate.ts(window(my_new_ser, start = c(2019, 2), end = c(2020, 1))),
aggregate.ts(window(my_new_ser, start = c(2020, 2), end = c(2021, 1)))),
rbind(aggregate.ts(window(out_raked3, start = c(2019, 2), end = c(2020, 1))),
aggregate.ts(window(out_raked3, start = c(2020, 2), end = c(2021, 1)))))
# Check the control total (fixed)
all.equal(my_series[, "cars_tot"], out_raked3[, "cars_tot"])