--- title: "iperform" output: rmarkdown::html_vignette description: "Comment utiliser les fonctions du pacakge iperform qui donnent les performances de l'evolution d'une série temporelle à une date donnée." vignette: > %\VignetteIndexEntry{iperform} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ## Introduction Décrire, résumer, modéliser et prédire font partie des principaux objectifs poursuivis lors de l'analyse d'une série temporelle. L’étape de la description, comme pour toutes les données, consiste souvent à des représentations graphiques telles que le chronogramme, l'histogramme, le diagramme retardé, et aux calculs des statistiques issuelles telles que la moyenne, la variance, le coefficients d’aplatissement et d’asymétrie. Dans les domaines de finance, de comptabilité ou de marketing opérationnel, les experts suivent au quotidien l'évolution de leurs activités en comparant à chaque fois les résultats d'une date (ou d'une période) par rapport à une date (ou une période) antérieure, par rapport aux résultats du marché global ou par rapport aux résultats de leurs concurrents directs. On parle là de concept de *performance*. Si on note par $x_t$ ~ $\left\{x_t : t = 1, · · · , n\right\}$ une série temporelle où $t$ represente le temps, les performances les plus souvent sont : * La performance *year-to-date* (YTD) : qui conrespond au résultat cumulé commençant le premier jour de l’année civile ou de l'exercice en cours jusqu’à la date actuelle, $$YTD_x = \sum_{t=1}^{n} x_{t}$$ $x_1$ correspond à la valeur de la série au 1er janvier, et $x_n$ à la valeur de la série à la date actuelle. * La performance *month-to-date* (MTD) : qui conrespond au résultat cumulé commençant le premier jour du mois en cours jusqu’à la date actuelle au cours du même mois, $$MTD_x = \sum_{t=1}^{n} x_{t}$$ $x_1$ correspond à la valeur de la série au 1er jour du mois, et $x_n$ à la valeur de la série à la date actuelle au cours du même mois. * La performance *week-to-date* (WTD) : qui conrespond au résultat cumulé commençant le permier jour de la semaine jusqu’à la date actuelle au cours de la même semaine. $$WTD_x = \sum_{t=1}^{n} x_{t}$$ $x_1$ correspond à la valeur de la série au 1er jour de la semaine, et $x_n$ à la valeur de la série à la date actuelle au cours de la même semaine. On peut egalement parler des concepts de *day-to-date* (pour la durée écoulée au cours d'une journée pour ceux qui suivent l’activité par heure) ou *quater-to-date* (pour le résultat cumulé sur un trimestre) ou encore *full month*, *full year*, etc pour designer la totalité de la periode indiquée. Ces concepts représentent à eux seuls près de 90% de l’information de pilotage des activités des analystes du secteur bancaire, bourse, télécommunication avant d'arriver à la modélisation et la prédiction des résultats futurs. Avec la révolution des solutions Big Data sur la visualisation des données, plusieurs tableaux de bord utilisent ces concepts en combinaison avec les variations par rapport aux dates ou périodes antérieures pour enrichir l'histoire lors de la présentation des données, des résultats ou de la performance de l’activité. Cette vignette décrit l'utilisation des differentes fonctions offertes par le package *iperform* pour répondre à ce besoin devenu de plus en plus important avec la révolution des données. Le package *iperform* est une boite à outil qui permet de calculer les performances d’une série temporelle en une date ou sur une période bien spécifique. Couplé avec le package R *lubridate*, le package offre en cette prémière version les principales fonctions que voici regroupées en quatre (4) catégories : ### Les performances * `dday()` qui renvoie la valeur d'une série à une date donnée en argument, * `wtd()` qui renvoie la somme des valeurs de la série depuis le début de la semaine correspondante à la date renseignée en argurment, * `mtd()` qui renvoie la somme des valeurs de la série depuis le début du mois correspondant à la date renseignée en argurment, * `qtd()` qui renvoie la somme des valeurs de la série depuis le début du trimestre correspondant à la date renseignée en argurment, * `htd()` qui renvoie la somme des valeurs de la série depuis le début du semestre correspondant à la date renseignée en argurment, * `ytd()` qui renvoie la somme des valeurs de la série depuis le début de l’année correspondante à la date renseignée en argurment, * `full_w()` qui renvoie la somme des valeurs de la série depuis sur tout la semaine correspondant à la date renseignée en argurment, * `full_m()` qui renvoie la somme des valeurs de la série depuis sur tout le mois correspondant à la date renseignée en argurment, * `full_q()` qui renvoie la somme des valeurs de la série depuis sur tout le trimestre correspondant à la date renseignée en argurment, * `full_h()` qui renvoie la somme des valeurs de la série depuis sur tout le semestre correspondant à la date renseignée en argurment, * `full_y()` qui renvoie la somme des valeurs de la série depuis sur toute l’année correspondant à la date renseignée en argurment, ### Les aperçus * `taux_v()` qui renvoie la variation en pourcentage (`%`) entre la valeur observée de la série temporelle en une date par rapport à une autre date du depart (une date passée). * `overview()` qui renvoie à l'image de la fonction `summary()`, un résumé des performances couplées avec des variations par rapport aux dates ou périodes antérieures de la série. ### Les prévisions * `forecast_m()` qui renvoie une somme estimée sur une période de la série en tenant compte de la performance *month-to-date*. La fonction comprend un argument qui permet d'utiliser un modèle spécifique de prédiction. ### Les transformations * `mean_m()` qui renvoie un nouveau jeu des données créé après transformation de la série initiales. Dans cette vignette, on présente les mecanismes des calculs derrière ces fonctions. ## Exemples Pour commencer, nous allons charger quelques packages nécessaires dont nous avons besoin ```{r setup, message=FALSE} library(lubridate) library(iperform) library(ggplot2) ``` ### 0. Description des données Nous allons illustré le fonctionnement de ces fonctions à l'aide d'un jeu de données contenant les indicateurs de l’activité du service voix mobile d'un operateur de téléphonie mobile anonyme[^n1]. ```{r} data(voix_mobile) ``` Ce jeu des données contient 4 variables : * `date`, variable de type date qui part du 1er janvier 2021 au 30 septembre 2023, * `Parc`, variable de type numeric qui renseigne le nombre des clients qui ont effectué au moin un appel sortant, * `Usage`, variable de type numeric qui renseigne le nombre des minutes consommées par l'ensemble des clients lors des appels, et * `Revenu`, variable de type numeric qui renseigne le revenu généré par les usages des clients à un tarif quelconque. ```{r} head(voix_mobile) ``` Un petit resumé sur des données ```{r} summary(voix_mobile) ``` La variable *Revenu* sur quoi on va se focaliser varie de `r min(voix_mobile$Revenu)` usd à `r max(voix_mobile$Revenu)` usd, avec une moyenne de `r mean(voix_mobile$Revenu)` usd. Elle a une variance de `r round(var(voix_mobile$Revenu))` et un écart type de `r round(sd(voix_mobile$Revenu))`. La valeur de *p-value < 0,05* de la sortie du test de normalité de Shapiro ci-dessous indique que la distribution des données est significativement différente de la distribution normale. Voilà le peu qu'on puisse dire, hormis les représentations graphiques sur ce qui est de la description de cette série. Le phénomène est observé entre le `r min(voix_mobile$date)` et le `r max(voix_mobile$date)`. ```{r} shapiro.test(voix_mobile$Revenu) ``` ### 1. La fonction *dday()* Pour connaitre le `Revenu` que l'ensemble des clients ont généré en date du *11 août 2023*, on utilise la fonction `dday()` comme suit : ```{r} dday(data = voix_mobile, date = "2023-08-11", d = 0, x = "Revenu", unite = 1, decimal = 0) ``` Les arguments de la fonction * `data` le jeu des données qui contient l'ensemble des données à exploiter, * `date` un character qui renseine la date à laquelle on cherche l'information, * `d` un entier qui determine le decalage des jours à prendre, la valeur par défaut vaut `0`. si `d=1`, on prendra la date du *10 août 2023*, * `unite` un numeric qui renseigne l'echel des valeurs qu'on souhaite avoir. sa valeur par defaut vaut `1`. Si `unite=1000`, la fonction va renvoyer une valeur diviser par `1000`, et * `decimal` un entier designant le nombre de chiffre après la virgule qu'on souhaite afficher si le résultat est un decimal. Sa valeur par défaut vaut `0`. La fonction renvoit la valeur `0` si la date renseignée par l'utilisateur ne fait pas partie des dates de la série, à l'exemple de la du *11 decembre 2023*: ```{r} dday(data = voix_mobile, date = "2023-12-11", d = 0, x = "Revenu", unite = 1, decimal = 0) ``` ### 2. La fonction *mtd()* Pour connaître la performance *month-to-date* du revenu réalisée en date du *11 août 2023*, c'est-à-dire la somme des valeurs partant du *01 août 2023* au *11 août 2023* inclus, on utilise la fonction `mtd()` comme suit : ```{r} mtd(data = voix_mobile, date = "2023-08-11", m = 0, x = "Revenu", unite = 1, decimal = 0) ``` ici, seul l'argument `m` est nouveau, les autres ont la même utilité que pour la fonction `dday()`. * `m` un entier qui determine le decalage du mois à prendre, la valeur par défaut vaut `0`. si `m=1`, on prendra la date du *11 juillet 2023*. ### 3. La fonction *ytd()* Pour connaître la performance *year-to-date* du revenu réalisée en date du *11 août 2023*, c'est-à-dire la somme des valeurs partant du *01 janvier 2023* au *11 août 2023* inclus, on utilise la fonction `ytd()` comme suit : ```{r} ytd(data = voix_mobile, date = "2023-08-11", a = 0, x = "Revenu", unite = 1000, decimal = 0) ``` idem pour les arguments. * `a` un entier qui determine le decalage de l’année à prendre, la valeur par défaut vaut `0`. Si `a=1`, on prendra la date du *11 août 2022*. ### 4. La fonction *wtd()* Pour connaître la performance *week-to-date* du revenu réalisée en date du *11 août 2023*, on part du fait que la date *11 août 2023* est un vendredi, donc le 6e de la semaine en considerant le dimanche *06 août 2023* comme 1er jour. Ainsi, on calcule la somme des valeurs partant du *06* au *11* inclus en utilisant la fonction `wtd()` comme suit : ```{r} wtd(data = voix_mobile, date = "2023-08-11", w = 0, x = "Revenu", unite = 1, decimal = 0) ``` idem pour les arguments. * `w` un entier qui determine le decalage de la semaine à prendre, la valeur par défaut vaut `0`. Si `w=1`, on prendra la date du vendredi *4 août 2022*. ### 5. La fonction *full_m()* Cette fonction calcule la somme des valeurs d'une série au cours d'un mois. Le mois est déterminé par la date qu'on passe en argument à la fonction. Ainsi le code ci-dessous va nous renvoyer le total jusqu’en date du *31 août 2023* : ```{r} full_m(data = voix_mobile, date = "2023-08-11", x = "Revenu", unite = 1000, decimal = 0, cumul = FALSE) ``` Et cela quelque soit la date qu'on introduit en argument si cette dernière est comprise entre *01 août 2023* et *31 août 2023*. On peut le verifier avec le code ci-dessous : ```{r} full_m(data = voix_mobile, date = "2023-08-25", x = "Revenu", unite = 1000) ``` ### 6. La fonction *forecast_m()* Pour cette version du package, la fonction `forecast_m()` ne fait pas grande chose, si ce n’est de calculer le total qu'on pourrait avoir sur un mois, connaissant sa performance *month-to-date* et le nombre du jour restant dans le même mois. Par exemple, si on place à la date du *2023-08-11*, le forecast en cette date vaut : ```{r} forecast_m(data = voix_mobile, date = "2023-08-11", x = "Revenu", unite = 1000, decimal = 0, cumul = FALSE, mod = "NULL") ``` En constate que cette valeur sera différente en fonction de la date à laquelle on se place au cours du mois : ```{r} vec_date = c("2023-08-20", "2023-08-25", "2023-08-28", "2023-08-30", "2023-08-31") for (d in vec_date) { F = forecast_m(data = voix_mobile, date = d, x = "Revenu", unite = 1000) print(F) } ``` L'arguments `mod` * `mod`, un character qui determine le type de modèle à utiliser pour faire la prediction. Sa valeur par defaut est `NULL` et l'alternative ne fait pas l'objet de cette version. Mais au moins, on constate que pour ce modèle, plus on donne en argument une date qui est proche de la clôture du mois, plus la fonction renvoit une valeur proche de la fonction `full_m`. ### 7. La fonction *taux_v()* Le taux de variation (tv) est la mesure de l'évolution d'un phénomène observé dans le temps. Si on note par $x_a$ la valeur actuelle observée et $x_d$ la valeur observée au départ (dans le passé), on a : $$tv = \frac{x_a - x_d}{x_d}$$ Cette formule permet restreindre la définition du taux de variation qu'avec $x_d \ne 0$ pour exclure le cas de division par `0`. En pratique, on lit le résultat en pourcentage, c’est-à-dire $tv*100$. Ce concept de *variation* ou *taux de variation* est trop utilisé dans les secteurs d’activité auxquels nous travaillons, les variations les plus fréquentes sont les suivantes : * La variation *DtD* en date du *2023-08-11* : elle consiste à calculer la variation du revenu en cette date par rapport à la date du *2023-08-10*, c-est-à-dire: $$DoD = \frac{dday - dday_1}{dday_1}$$ * La variation *MtD* en date du *2023-08-11* : elle consite à calculer la variation *MTD* au *2023-08-11* par rapport au *MTD* en date du *2023-07-11* (on note souvent par $MTD_1$) : $$SLPM = \frac{MTD - MTD_1}{MTD_1}$$ * La variation *YtD* en date du *2023-08-11* : elle consite à calculer la variation *YTD* au *2023-08-11* par rapport au *YTD* en date du *2022-08-11* (on note souvent par $YTD_1$) : $$YoY = \frac{YTD - YTD_1}{YTD_1}$$ On parle aussi de la variation *WtD*, *MtM*, *YoY*, etc. Ainsi, si on souhaite calculer le taux de variation du revenu du *11 août 2023* par rapport au *10 août 2023*, on utilise la fonction `taux_v()` comme suit : ```{r} taux_v(data = voix_mobile, date = "2023-08-11", x = "Revenu", p = -1) ``` par rapport au *04 août 2023* : ```{r} taux_v(data = voix_mobile, date = "2023-08-11", x = "Revenu") ``` Par rapport au *11 juillet 2023* : ```{r} taux_v(data = voix_mobile, date = "2023-08-11", x = "Revenu", variation = "mtd") ``` ### 8. La fonction *overview()* On a l'habitude d’utiliser la fonction de base `summary()` qui renvoie les statistiques issuelles, cependant ces paramètres entrent rarement dans le narratif des analystes des données du secteur susmentionnés. Pour reporter les résultats, les experts presentent des apercus globaux où ils parlent des performances *YTD*, *MTD*, *WTD*, etc... et leurs variations par rapport aux périodes antérieures. Ainsi, si on souhaite avoir un aperçu du revenu en date du *2023-08-11*, on utilise la fonction `overview()` comme suit : ```{r overview, eval = FALSE} overview(data = voix_mobile, date = "2023-08-11", x = "Revenu", unite = 1, decimal = 2, cumul = FALSE, freq = "full") ``` Lecture de la sortie du code R : ```{r, echo=FALSE} resultat <- overview(data = voix_mobile, date = "2023-08-11", x = "Revenu", unite = 1, decimal = 2, cumul = FALSE, freq = "full") resultat ``` On pourra par exemple dire : En date du *2023-08-11*, l'operateur mobile a réalisé un chiffre d'affaire de `r resultat[, "MTD"]` usd en MTD, soit une `r if (resultat[, "SPLM"] < 0) {"baisse"} else {"hausse"}` de `r paste(resultat[, "SPLM"], "%", sep="")` comparé à la même periode du mois passé. Avec le nombre de jours restant au cours du mois, on prévoit un total de `r resultat[, "FORECAST"]` usd à la fin mois, ce qui fera une `r if (resultat[, "MoM"] < 0) {"baisse"} else {"hausse"}` de `r paste(resultat[, "MoM"], "%", sep="")` par rapport à tout le mois de Juillet. En outre, la performance year-to-date atteint `r resultat[, "YTD"]` usd, soit une `r if (resultat[, "YoY"] < 0) {"baisse"} else {"hausse"}` de `r paste(resultat[, "YoY"], "%", sep="")` par rapport à l’année passée. Certe, ce discours ne represente pas les causes qui expliquent les resultats en chaque période ni les différentes variations, mais au moins, raconte une histoire évolutive et un aperçu global de la perfomance de l’activité. Il ne restera qu'au rapporteur d'enrichir son histoire avec les resultats des analyses des causes à effet. ### 9. La fonction *mean_m()* Cette fonction transforme une série temporelle à une série de moyenne mobile où chaque terme de la série devient la moyenne de lui-même avec ses sept(6) derniers termes précédants. A la sortie, la fonction renvoie un jeu des données où chaque colonne renseigne les données d'une année pour être superposées sur un graphe. Exemple d'utilisation ```{r} df_mb = mean_m(data = voix_mobile, x = "Revenu", unite = 1, decimal = 0) head(df_mb, 10) ``` * Tous les arguments ont le même sens sens que dans les fonctions précédentes, * La colonne date est de longueur `n` inférieur ou egale à `365`. Elle depend de l'etendue de la période du jeu des données initial, * Les moyennes calculées sont classées par année civiles, autant on a des années, autant on aura des colonnes, * L'argument `borne` permet de masquer la colonne `Min` et `Max` de chaque ligne. [^n1]: Chiffres simulés à partir du rapport trimestriel de l'Autorité de Régulation de Poste et de Télécommunication : [ARPTC-RDC](https://arptc.gouv.cd/observatoire/).