Construire les éléments des problèmes d'équilibrage.
Source :R/tsbalancing.R
build_balancing_problem.Rd
Cette fonction est utilisée à l'interne par tsbalancing()
pour construire les éléments des problèmes
d'équilibrage. Elle peut également être utile pour dériver manuellement (en dehors du contexte de tsbalancing()
)
les séries indirectes associées aux contraintes d'équilibrage d'égalité.
Utilisation
build_balancing_problem(
in_ts,
problem_specs_df,
in_ts_name = deparse1(substitute(in_ts)),
ts_freq = stats::frequency(in_ts),
periods = gs.time2str(in_ts),
n_per = nrow(as.matrix(in_ts)),
specs_df_name = deparse1(substitute(problem_specs_df)),
temporal_grp_periodicity = 1,
alter_pos = 1,
alter_neg = 1,
alter_mix = 1,
lower_bound = -Inf,
upper_bound = Inf,
validation_only = FALSE
)
Arguments
- in_ts
(obligatoire)
Objet de type série chronologique (classe « ts » ou « mts ») qui contient les données des séries chronologiques à réconcilier. Il s'agit des données d'entrée (solutions initiales) des problèmes d'équilibrage (« balancing »).
- problem_specs_df
(obligatoire)
Data frame (object de classe « data.frame ») des spécifications du problème d'équilibrage. En utilisant un format clairsemé (épars) inspiré de la procédure LP de SAS/OR\(^\circledR\) (SAS Institute 2015), il ne contient que les informations pertinentes telles que les coefficients non nuls des contraintes d'équilibrage ainsi que les coefficients d'altérabilité et les bornes inférieures/supérieures à utiliser au lieu des valeurs par défaut (c.-à-d., les valeurs qui auraient la priorité sur celles définies avec les arguments
alter_pos
,alter_neg
,alter_mix
,alter_temporal
,lower_bound
etupper_bound
).Les informations sont fournies à l'aide de quatre variables obligatoires (
type
,col
,row
etcoef
) et d'une variable facultative (timeVal
). Un enregistrement (une rangée) dans le data frame des spécifications du problème définit soit une étiquette pour l'un des sept types d'éléments du problème d'équilibrage avec les colonnestype
etrow
(voir Enregistrements de définition d'étiquette ci-dessous) ou bien spécifie des coefficients (valeurs numériques) pour ces éléments du problème d'équilibrage avec les variablescol
,row
,coef
ettimeVal
(voir Enregistrements de spécification d'information ci-dessous).Enregistrements de définition d'étiquette (
type
n'est pas manquant (n'est pasNA
))type
(car) : mot-clé réservé identifiant le type d'élément du problème en cours de définition :EQ
: contrainte d'équilibrage d'égalité (\(=\))LE
: contrainte d'équilibrage d'inégalité de type inférieure ou égale (\(\le\))GE
: contrainte d'équilibrage d'inégalité de type supérieure ou égale (\(\ge\))lowerBd
: borne inférieure des valeurs de périodeupperBd
: borne supérieure des valeurs de périodealter
: coefficient d'altérabilité des valeurs de périodealterTmp
: coefficient d'altérabilité des totaux temporels
row
(car) : étiquette à associer à l'élément du problème (mot-clétype
)toutes les autres variables ne sont pas pertinentes et devraient contenir des données manquantes (valeurs
NA
)
Enregistrements de spécification d'information (
type
est manquant (estNA
))type
(car) : non applicable (NA
)col
(car) : nom de la série ou mot réservé_rhs_
pour spécifier la valeur du côté droit (RHS pour Right-Hand Side) d'une contrainte d'équilibrage.row
(car) : étiquette de l'élément du problème.coef
(num) : valeur de l'élément du problème :coefficient de la série dans la contrainte d'équilibrage ou valeur RHS
borne inférieure ou supérieure des valeurs de période de la série
coefficient d'altérabilité des valeurs de période ou des totaux temporels de la série
timeVal
(num) : valeur de temps optionnelle pour restreindre l'application des bornes ou coefficients d'altérabilité des séries à une période (ou groupe temporel) spécifique. Elle correspond à la valeur de temps, telle que renvoyée parstats::time()
, pour une période (observation) donnée des séries chronologiques d'entrée (argumentin_ts
) et correspond conceptuellement à \(ann\acute{e}e + (p\acute{e}riode - 1) / fr\acute{e}quence\).
Notez que les chaînes de caractères vides (
""
ou''
) pour les variables de type caractère sont interprétées comme manquantes (NA
) par la fonction. La variablerow
identifie les éléments du problème d'équilibrage et est la variable clé qui fait le lien entre les deux types d'enregistrements. La même étiquette (row
) ne peut être associée à plus d'un type d'éléments du problème (type
) et plusieurs étiquettes (row
) ne peuvent pas être définies pour un même type d'éléments du problème donné (type
), à l'exception des contraintes d'équilibrage (valeurs"EQ"
,"LE"
et"GE"
de la colonnetype
). Voici certaines caractéristiques conviviales du data frame des spécifications du problème :L'ordre des enregistrements (rangées) n'est pas important.
Les valeurs des variables de type caractère (
type
,row
etcol
) ne sont pas sensibles à la casse (ex., les chaînes de caractères"Constraint 1"
et"CONSTRAINT 1"
pour la variablerow
seraient considérées comme une même étiquette d'élément du problème), sauf lorsquecol
est utilisé pour spécifier un nom de série (une colonne de l'objet d'entrée de type série chronologique) où la sensibilité à la casse est appliquée.Les noms des variables du data frame des spécifications du problème ne sont pas non plus sensibles à la casse (ex.,
type
,Type
ouTYPE
sont tous des noms de variable valides) ettime_val
est un nom de variable accepté (au lieu detimeVal
).
Enfin, le tableau suivant dresse la liste des alias valides (acceptés) pour les mots-clés
type
(type d'éléments du problème) :Mot-clé Alias EQ
==
,=
LE
<=
,<
GE
>=
,>
lowerBd
lowerBound
,lowerBnd
, + mêmes termes avec '_', '.' ou ' ' entre les motsupperBd
upperBound
,upperBnd
, + mêmes termes avec '_', '.' ou ' ' entre les motsalterTmp
alterTemporal
,alterTemp
, + mêmes termes avec '_', '.' ou ' ' entre les motsL'examen des Exemples devrait aider à conceptualiser le data frame des spécifications du problème d'équilibrage.
- in_ts_name
(optionnel)
Chaîne de caractères contenant la valeur de l'argument
in_ts
.La valeur par défaut est
in_ts_name = deparse1(substitute(in_ts))
.- ts_freq
(optionnel)
Fréquence de l'object the type série chronologique (argument
in_ts
).La valeur par défaut est
ts_freq = stats::frequency(in_ts)
.- periods
(optionnel)
Vecteur de chaînes de caractères décrivant les périodes de l'object the type série chronologique (argument
in_ts
).La valeur par défaut est
periods = gs.time2str(in_ts)
.- n_per
(optionnel)
Nombre de périodes de l'object the type série chronologique (argument
in_ts
).La valeur par défaut est
n_per = nrow(as.matrix(in_ts))
.- specs_df_name
(optionnel)
Chaîne de caractères contenant la valeur de l'argument
problem_specs_df
.La valeur par défaut est
specs_df_name = deparse1(substitute(problem_specs_df))
.- temporal_grp_periodicity
(optionnel)
Nombre entier positif définissant le nombre de périodes dans les groupes temporels pour lesquels les totaux doivent être préservés. Par exemple, spécifiez
temporal_grp_periodicity = 3
avec des séries chronologiques mensuelles pour la préservation des totaux trimestriels ettemporal_grp_periodicity = 12
(outemporal_grp_periodicity = frequency(in_ts)
) pour la préservation des totaux annuels. Spécifiertemporal_grp_periodicity = 1
(défaut) correspond à un traitement période par période sans préservation des totaux temporels.La valeur par défaut est
temporal_grp_periodicity = 1
(traitement période par période sans préservation des totaux temporels).- alter_pos
(optionnel)
Nombre réel non négatif spécifiant le coefficient d'altérabilité par défaut associé aux valeurs des séries chronologiques avec des coefficients positifs dans toutes les contraintes d'équilibrage dans lesquelles elles sont impliquées (ex., les séries composantes dans les problèmes de ratissage (« raking ») de tables d'agrégation). Les coefficients d'altérabilité fournis dans le data frame des spécifications du problème (argument
problem_specs_df
) remplacent cette valeur.La valeur par défaut est
alter_pos = 1.0
(valeurs non contraignantes).- alter_neg
(optionnel)
Nombre réel non négatif spécifiant le coefficient d'altérabilité par défaut associé aux valeurs des séries chronologiques avec des coefficients négatifs dans toutes les contraintes d'équilibrage dans lesquelles elles sont impliquées (ex., les séries de total de marge dans les problèmes de ratissage (« raking ») de tables d'agrégation). Les coefficients d'altérabilité fournis dans le data frame des spécifications du problème (argument
problem_specs_df
) remplacent cette valeur.La valeur par défaut est
alter_neg = 1.0
(valeurs non contraignantes).- alter_mix
(optionnel)
Nombre réel non négatif spécifiant le coefficient d'altérabilité par défaut associé aux valeurs des séries chronologiques avec un mélange de coefficients positifs et négatifs dans les contraintes d'équilibrage dans lesquelles elles sont impliquées. Les coefficients d'altérabilité fournis dans le data frame des spécifications du problème (argument
problem_specs_df
) remplacent cette valeur.La valeur par défaut est
alter_mix = 1.0
(valeurs non contraignantes).- lower_bound
(optionnel)
Nombre réel spécifiant la borne inférieure par défaut pour les valeurs des séries chronologiques. Les bornes inférieures fournies dans le data frame des spécifications du problème (argument
problem_specs_df
) remplacent cette valeur.La valeur par défaut est
lower_bound = -Inf
(non borné).- upper_bound
(optionnel)
Nombre réel spécifiant la borne supérieure par défaut pour les valeurs des séries chronologiques. Les bornes supérieures fournies dans le data frame des spécifications du problème (argument
problem_specs_df
) remplacent cette valeur.La valeur par défaut est
upper_bound = Inf
(non borné).- validation_only
(optionnel)
Argument logique (logical) spécifiant si la fonction doit uniquement effectuer la validation des données d'entrée ou non. Lorsque
validation_only = TRUE
, les contraintes d'équilibrage et les bornes (inférieures et supérieures) des valeurs de période spécifiées sont validées par rapport aux données de séries chronologiques d'entrée, en permettant des écarts jusqu'à la valeur spécifiée avec l'argumentvalidation_tol
. Sinon, lorsquevalidation_only = FALSE
(par défaut), les données d'entrée sont d'abord réconciliées et les données résultantes (en sortie) sont ensuite validées.La valeur par défaut est
validation_only = FALSE
.
Valeur de retour
Une liste avec les éléments des problèmes d'équilibrage (excluant l'information sur les totaux temporels) :
labels_df
: version nettoyée des enregistrements de définition d'étiquette provenant deproblem_specs_df
(enregistrements oùtype
n'est pas manquant (n'est pasNA
)); colonnes supplémentaires :type.lc
:tolower(type)
row.lc
:tolower(row)
con.flag
:type.lc %in% c("eq", "le", "ge")
coefs_df
: version nettoyée des enregistrements de spécification d'information provenant deproblem_specs_df
(enregistrements oùtype
est manquant (estNA
)); colonnes supplémentaires :row.lc
:tolower(row)
con.flag
:labels_df$con.flag
attribuée à traversrow.lc
values_ts
: version réduite dein_ts
avec seulement les séries pertinentes (voir vecteurser_names
)lb
: information sur les bornes inférieures (type.lc = "lowerbd"
) des séries pertinentes; liste avec les éléments suivants :coefs_ts
: object « mts » contenant les bornes inférieures des séries pertientes (voir vecteurser_names
)nondated_coefs
: vecteur des bornes non datées deproblem_specs_df
(timeVal
estNA
)nondated_id_vec
: vecteur d'identificateurs deser_names
associés au vecteurnondated_coefs
dated_id_vec
: vecteur d'identificateurs deser_names
associés aux bornes inférieures datées deproblem_specs_df
(timeVal
n'est pasNA
)
ub
: équivalent delb
pour les bornes supérieures (type.lc = "upperbd"
)alter
: équivalent delb
pour les coefficients d'altérabilité des valeurs de période (type.lc = "alter"
)altertmp
: équivalent delb
pour les coefficients d'altérabilité des totaux temporels (type.lc = "altertmp"
)ser_names
: vecteur des noms de séries pertinentes (ensemble de séries impliquées dans les contraintes d'équilibrage)pos_ser
: vecteur des noms de séries qui n'ont que des coefficients non nuls positifs à travers toutes les contraintesneg_ser
: vecteur des noms de séries qui n'ont que des coefficients non nuls négatifs à travers toutes les contraintesmix_ser
: vecteur des noms de séries qui ont des coefficients non nuls positifs et négatifs à travers toutes les contraintesA1
,op1
,b1
: éléments des contraintes d'équilibrage pour les problèmes impliquant une seule période (ex., chacune des périodes d'un groupe temporel incomplet)A2
,op2
,b2
: éléments des contraintes d'équilibrage pour les problèmes impliquanttemporal_grp_periodicity
périodes (ex., l'ensemble des périodes d'un groupe temporel complet)
Détails
Voir tsbalancing()
pour une description détaillée des problèmes d'équilibrage de séries chronologiques.
Toute valeur manquante (NA
) trouvée dans l'objet de série chronologique d'entrée (argument in_ts
) serait remplacée par 0
dans values_ts
et déclencherait un message d'avertissement.
Les éléments renvoyés des problèmes d'équilibrage n'incluent pas les totaux temporels implicites (c.-à-d., les éléments
A2
, op2
et b2
ne contiennent que les contraintes d'équilibrage).
Les éléments A2
, op2
et b2
d'un problème d'équilibrage impliquant plusieurs périodes (lorsque
temporal_grp_periodicity > 1
) sont construits colonne par colonne (selon le principe « column-major order » en anglais),
ce qui correspond au comportement par défaut de R lors de la conversion d'objets de la classe « matrix » en vecteurs.
Autrement dit, les contraintes d'équilibrage correspondent conceptuellement à :
A1 %*% values_ts[t, ] op1 b1
pour des problèmes impliquant une seule période (t
)A2 %*% as.vector(values_ts[t1:t2, ]) op2 b2
pour des problèmes impliquanttemporal_grp_periodicity
périodes (t1:t2
)
Notes :
L'argument
alter_temporal
n'a pas encore été appliqué à ce stade etaltertmp$coefs_ts
ne contient que les coefficients spécifiés dans le data frame des spécifications du problème (argumentproblem_specs_df
). Autrement dit,altertmp$coefs_ts
contient des valeurs manquantes (NA
) à l'exception des coefficients d'altérabilité de total temporel inclus dans (spécifiés avec)problem_specs_df
. Ceci est fait afin de faciliter l'identification du premier coefficient d'altérabilité non manquant (nonNA
) de chaque groupe temporel complet (à survenir ultérieurement, le cas échéant, danstsbalancing()
).La validation des arguments n'est pas effectuée ici ; on suppose (carrément) que la fonction est appelée par
tsbalancing()
où une validation complète des arguments est effectuée.
Exemples
######################################################################################
# Cadre de dérivation des séries indirectes avec les métadonnées de `tsbalancing()`
######################################################################################
#
# Il est supposé (convenu) que...
#
# a) Toutes les contraintes d'équilibrage sont des contraintes d'égalité (`type = EQ`).
# b) Toutes les contraintes n'ont qu'une seule série non contraignante (libre) : la
# série à dériver (c.-à-d., toutes les séries ont un coef. d'alt. de 0 sauf la
# série à dériver).
# c) Chaque contrainte dérive une série différente (une nouvelle série).
# d) Les contraintes sont les mêmes pour toutes les périodes (c.-à-d., il n'y a pas
# de coef. d'alt. « datés » spécifiés à l'aide de la colonne `timeVal`).
######################################################################################
# Dériver les 5 totaux de marge d'un cube de données à deux dimensions 2 x 3 en
# utilisant les métadonnées de `tsbalancing()` (les contraintes d'agrégation d'un
# cube de données respectent les hypothèses ci-dessus).
# Construire les spécifications du problème d'équilibrage à travers les métadonnées
# (plus simples) de ratissage.
mes_specs <- rkMeta_to_blSpecs(
data.frame(series = c("A1", "A2", "A3",
"B1", "B2", "B3"),
total1 = c(rep("totA", 3),
rep("totB", 3)),
total2 = rep(c("tot1", "tot2", "tot3"), 2)),
alterSeries = 0, # séries composantes contraignantes (fixes)
alterTotal1 = 1, # totaux de marge non contraignants (libres, à dériver)
alterTotal2 = 1) # totaux de marge non contraignants (libres, à dériver)
mes_specs
#> type col row coef timeVal
#> 1 EQ <NA> Marginal Total 1 (totA) NA NA
#> 2 <NA> A1 Marginal Total 1 (totA) 1 NA
#> 3 <NA> A2 Marginal Total 1 (totA) 1 NA
#> 4 <NA> A3 Marginal Total 1 (totA) 1 NA
#> 5 <NA> totA Marginal Total 1 (totA) -1 NA
#> 6 EQ <NA> Marginal Total 2 (totB) NA NA
#> 7 <NA> B1 Marginal Total 2 (totB) 1 NA
#> 8 <NA> B2 Marginal Total 2 (totB) 1 NA
#> 9 <NA> B3 Marginal Total 2 (totB) 1 NA
#> 10 <NA> totB Marginal Total 2 (totB) -1 NA
#> 11 EQ <NA> Marginal Total 3 (tot1) NA NA
#> 12 <NA> A1 Marginal Total 3 (tot1) 1 NA
#> 13 <NA> B1 Marginal Total 3 (tot1) 1 NA
#> 14 <NA> tot1 Marginal Total 3 (tot1) -1 NA
#> 15 EQ <NA> Marginal Total 4 (tot2) NA NA
#> 16 <NA> A2 Marginal Total 4 (tot2) 1 NA
#> 17 <NA> B2 Marginal Total 4 (tot2) 1 NA
#> 18 <NA> tot2 Marginal Total 4 (tot2) -1 NA
#> 19 EQ <NA> Marginal Total 5 (tot3) NA NA
#> 20 <NA> A3 Marginal Total 5 (tot3) 1 NA
#> 21 <NA> B3 Marginal Total 5 (tot3) 1 NA
#> 22 <NA> tot3 Marginal Total 5 (tot3) -1 NA
#> 23 alter <NA> Period Value Alterability NA NA
#> 24 <NA> A1 Period Value Alterability 0 NA
#> 25 <NA> A2 Period Value Alterability 0 NA
#> 26 <NA> A3 Period Value Alterability 0 NA
#> 27 <NA> B1 Period Value Alterability 0 NA
#> 28 <NA> B2 Period Value Alterability 0 NA
#> 29 <NA> B3 Period Value Alterability 0 NA
#> 30 <NA> totA Period Value Alterability 1 NA
#> 31 <NA> totB Period Value Alterability 1 NA
#> 32 <NA> tot1 Period Value Alterability 1 NA
#> 33 <NA> tot2 Period Value Alterability 1 NA
#> 34 <NA> tot3 Period Value Alterability 1 NA
# 6 périodes (trimestres) de données avec totaux de marge initialisés à zéro (0): ces
# derniers doivent OBLIGATOIREMENT exister dans les données d'entrée ET contenir des
# données valides (non `NA`).
mes_series <- ts(data.frame(A1 = c(12, 10, 12, 9, 15, 7),
B1 = c(20, 21, 15, 17, 19, 18),
A2 = c(14, 9, 8, 9, 11, 10),
B2 = c(20, 29, 20, 24, 21, 17),
A3 = c(13, 15, 17, 14, 16, 12),
B3 = c(24, 20, 30, 23, 21, 19),
tot1 = rep(0, 6),
tot2 = rep(0, 6),
tot3 = rep(0, 6),
totA = rep(0, 6),
totB = rep(0, 6)),
start = 2019, frequency = 4)
# Obtenir les éléments du problème d'équilibrage.
n_per <- nrow(mes_series)
p <- build_balancing_problem(mes_series, mes_specs,
temporal_grp_periodicity = n_per)
# `A2`, `op2` et `b2` définissent 30 constraintes (5 totaux de marge X 6 périodes)
# impliquant un total de 66 points de données (11 séries X 6 périodes) desquels 36
# réfèrent aux 6 séries composantes et 30 réfèrent aux 5 totaux de marge.
dim(p$A2)
#> [1] 30 66
# Obtenir les noms des totaux de marge (séries avec un coef. d'alt. non nul), dans
# l'ordre où les contraintes correspondantes apparaissent dans les spécifications
# (ordre de spécification des constraintes).
tmp <- p$coefs_df$col[p$coefs_df$con.flag]
noms_tot <- tmp[tmp %in% p$ser_names[p$alter$nondated_id_vec[p$alter$nondated_coefs != 0]]]
# Définir des drapeaux logiques identifiant les colonnes de total de marge :
# - `col_tot_logi1` : éléments à période unique (de longueur 11 = nombre de séries)
# - `col_tot_logi2` : éléments multi-périodes (de longueur 66 = nombre de points de
# données), selon le principe « column-major order » en anglais
# (l'ordre de construction des éléments de la matrice `A2`)
col_tot_logi1 <- p$ser_names %in% noms_tot
col_tot_logi2 <- rep(col_tot_logi1, each = n_per)
# Ordre des totaux de marge à dériver selon
# ... les colonnes des données d'entrée (objet « mts » `mes_series`)
p$ser_names[col_tot_logi1]
#> [1] "tot1" "tot2" "tot3" "totA" "totB"
# ... la spécification des contraintes (« data frame » `mes_specs`)
noms_tot
#> [1] "totA" "totB" "tot1" "tot2" "tot3"
# Calculer les 5 totaux de marge pour les 6 périodes.
# Note : le calcul suivant prend en compte les contraintes d'égalité linéaires
# générales, c.-à-d.,
# a) des valeurs non nulles du côté droit des contraintes (`b2`) et
# b) des coefficients de contrainte non nuls autres que 1 pour les séries
# composantes et -1 pour la série à dériver.
mes_series[, noms_tot] <- {
(
# Côté droit des contraintes
p$b2 -
# Sommes des composantes (« pondérées » par les coefficients des contraintes)
p$A2[, !col_tot_logi2, drop = FALSE] %*% as.vector(p$values_ts[, !col_tot_logi1])
) /
# Coefficients des séries dérivées : `t()` permet une recherche « par ligne » dans
# la matrice `A2` (c.-à-d., selon l'ordre de spécification des constraintes)
# Note: `diag(p$A2[, tot_col_logi2])` fonctionnerait si `p$ser_names[col_tot_logi1]`
# et `noms_tot` étaient identiques (même ordre pour les totaux); par contre,
# la recherche « par ligne » ci-dessous fonctionnera toujours (et est
# nécessaire dans le cas qui nous concerne).
t(p$A2[, col_tot_logi2])[t(p$A2[, col_tot_logi2]) != 0]
}
mes_series
#> A1 B1 A2 B2 A3 B3 tot1 tot2 tot3 totA totB
#> 2019 Q1 12 20 14 20 13 24 32 34 37 39 64
#> 2019 Q2 10 21 9 29 15 20 31 38 35 34 70
#> 2019 Q3 12 15 8 20 17 30 27 28 47 37 65
#> 2019 Q4 9 17 9 24 14 23 26 33 37 32 64
#> 2020 Q1 15 19 11 21 16 21 34 32 37 42 61
#> 2020 Q2 7 18 10 17 12 19 25 27 31 29 54