Techniques de cumul et d'agrégation de données sous R

L’analyse de données nécessite fréquemment de résumer des informations ou de calculer des cumuls basés sur des groupes. Que vous travailliez sur des séries temporelles, des données de recensement ou des ventes, R offre une vaste palette d'outils, allant des fonctions de base aux packages spécialisés du tidyverse.

La fonction aggregate : une approche fondamentale

La fonction aggregate en R est un outil puissant pour résumer des données en fonction de groupes. Imaginons que nous avons un data frame contenant des informations sur les ventes de produits dans différents magasins. Ce data frame contient trois colonnes : magasin, produit et montant. La fonction aggregate est un outil très utile pour résumer des données en R. Elle permet d’effectuer des calculs statistiques sur des sous-ensembles de données, facilitant ainsi l’analyse et la compréhension des données.

Schéma illustrant le fonctionnement de la fonction aggregate sur un jeu de données

Limites des boucles et efficacité de la vectorisation

Il existe deux sortes de boucles dans R. Avant de présenter chacune de ces fonctions, il est nécessaire de préciser que les boucles ne sont pas le point fort de R. Quand on connaît le nombre d’itérations à l’avance, on peut utiliser la fonction for(). On peut utiliser la fonction for() pour remplir les éléments d’une liste, ou d’un vecteur. À chaque itération, R doit trouver le vecteur de destination en mémoire, créer un nouveau vecteur qui permettra de contenir plus de données, copier données depuis l’ancien vecteur pour les insérer dans le nouveau, et enfin supprimer l’ancien vecteur (Ross 2014). C’est une opération coûteuse en temps. Un moyen de rendre cette allocation plus efficace est de créer a priori le vecteur ou la liste en le remplissant avec des données manquantes.

Comme indiqué plus haut, les boucles sont des opérations lentes en R. Il est cependant possible, dans de nombreux cas, d’éviter de les employer, en ayant recours à la vectorisation : au lieu d’appliquer une fonction à un scalaire, on l’applique à un vecteur. En fait, nous avons déjà eu recours à maintes reprises aux calculs vectoriels. En effet, lorsque nous avons procédé à des additions, des multiplications, etc. Derrière ce code, la fonction log() applique la fonction logarithme sur toutes les valeurs du vecteur donné en argument. La fonction sum(), quant à elle, se charge d’additionner tous les éléments du vecteur qui lui est donné en argument. Ces deux fonctions utilisent la vectorisation, mais d’une manière différente : la fonction log() applique une opération à chaque élément d’un vecteur, tandis que la fonction sum() produit un résultat basé sur la totalité du vecteur.

Tips - Quelle est la différence entre une image vectorielle et une image matricielle ?

Les fonctionnelles : la famille apply et le package purrr

Il existe des fonctions, rédigées en C, qui effectuent des boucles for. On leur donne souvent le nom de « fonctions de la famille apply ». Il ne s’agit pas de la vectorisation, mais ces fonctions sont souvent mentionnées dès que l’on parle de ce sujet. Ce sont des fonctionnelles qui prennent une fonction en input et retournent un vecteur en output (Wickham 2014). Ces fonctions sont très utilisées, mais elles souffrent d’un manque d’uniformité. En effet, elles ont été rédigées par des personnes différentes, ayant chacune leur convention. Le package {plyr} remédie à ce problème, et ajoute par la même occasion des fonctions supplémentaires, pour couvrir plus de cas que les « fonctions de la famille apply’’.

Nous allons donc nous attarder dans un premier temps sur les fonctions du package {purrr}. Le package {purrr} propose de nombreuses fonctions permettant de manipuler les listes et les tableaux de données. Dans cette partie, nous allons nous concentrer sur les fonctions de ce package qui permettent d’appliquer des opérations sur chaque élément d’une liste ou sur chaque colonne d’un tableau de données. Le nom de ces fonctions commence par le préfixe map.

Manipulation avancée avec dplyr

dplyr est un autre élément du tidyverse qui met à disposition des fonctions utiles pour manipuler et transformer des données. Comparé au langage R de base, utiliser dplyr est souvent plus rapide et vous garantit que si les données en entrée sont propres, les données transformées le seront aussi. Ce qui est peut-être encore plus important, dplyr facilite la lecture de votre code et utilise des « verbes » qui sont intuitifs la plupart du temps. Chaque fonction dans dplyr correspond à l’un de ces verbes, dont les plus importants sont : filter, select, arrange, mutate et summarise.

L’opérateur pipe (%>%) fait partie du paquet magrittr mis au point par Stefan Milton Bache et Hadley Wickham et est inclus dans le tidyverse. L’opérateur pipe nous permet de déclarer ce qui est à gauche du pipe comme le premier élément de la fonction qui est indiquée à droite. Cela peut sembler étrange au premier abord, mais une fois appris, vous trouverez qu’il rend votre code plus lisible en évitant l’imbrication des opérations.

Infographie montrant le pipeline de traitement des données avec dplyr

Calculs de cumuls et agrégations conditionnelles

Si vous souhaitez calculer des cumuls, par exemple pour compter le nombre de jours consécutifs sans précipitation, les fonctions de type cumsum ou des approches avec dplyr sont préférables aux boucles. La fonction summarise() est une fonction habituellement utilisée pour créer un tableau de données statistiques récapitulatives. À l’inverse de mutate(), quand une fonction summarise est appelée, elle retourne une seule information. Ainsi, si on veut construire des statistiques agrégées non sur l’ensemble de la table, mais pour chacune des modalités d’une ou de plusieurs variables de la table, on utilise le groupement.

La fonction group_by() combinée à summarise() permet d'effectuer des calculs par catégorie de manière propre et efficace. Par exemple :

# Exemple de cumul par groupedonnees %>% group_by(magasin) %>% mutate(cumul_ventes = cumsum(montant))

Gestion des données manquantes et statistiques descriptives

Les fonctions min, max, mean, median et sd, ainsi que quelques autres fonctions, ont un argument en commun nommé na.rm. Cet argument sert à indiquer à la fonction comment agir en présence de données manquantes (NA). Par défaut, na.rm prend la valeur FALSE pour ces fonctions. Cette valeur signifie que les données manquantes ne doivent pas être retirées avant d’effectuer le calcul. Cependant, en présence de données manquantes, ces fonctions ne sont pas en mesure de calculer des statistiques. Notons que la fonction na.omit permet de retirer les observations manquantes d’un objet R.

Les fonctions cummin et cummax calculent les minimums et les maximums cumulatifs. Ces fonctions sont utiles pour remplacer des valeurs par un seuil. En complément, la fonction table permet de compter le nombre d’occurrences de chacune des modalités d’une variable catégorique dans des données. La fonction ftable retourne un tableau de fréquences sous la forme d’une table « plate » dans le cas d’un croisement de 3 variables ou plus, plutôt que sous la forme d’un array comme le fait la fonction table.

Diagramme des différentes fonctions de cumul disponibles dans R

Simulation et génération de données

En R, les fonctions r* permettent de générer pseudo-aléatoirement des observations selon une certaine distribution désignée par *. Par exemple, voici la représentation graphique de 3 échantillons générés aléatoirement selon 3 distributions différentes : des distributions normale, uniforme continue et khi-deux. Pour chaque échantillon, nous traçons l’histogramme des observations simulées pour représenter leur densité empirique. Comme nous pouvons le constater sur ces graphiques, la distribution empirique des observations générées avec ces fonctions se rapproche vraiment de la distribution théorique demandée.

La fonction set.seed permet de fixer le germe du générateur de nombres aléatoires (RNG) à partir d’une seule valeur entière. Il existe des fonctions R pour faire des tests statistiques de base. Lorsque nous connaissons la valeur d’une statistique de test ainsi que sa loi sous l’hypothèse nulle, il est possible de calculer en R le seuil observé du test avec la bonne fonction p*.

Ajustement de modèles et manipulation des sorties

Ces fonctions d’ajustement de modèles prennent obligatoirement en entrée une formule R assignée à l’argument formula. Une formule s’écrit sous la forme y ~ x1 + x2y représente la variable réponse et x1 et x2 des variables explicatives. Certaines transformations pourraient faire intervenir un ou des opérateurs ayant une signification modifiée dans la partie de droite d’une formule. Oui, c’est possible grâce à la fonction I. Il faut encadrer l’opération arithmétique à effectuer dans la formule d’un appel à la fonction I. Par exemple, y ~ I(x1 + x2) ajuste un modèle à une seule variable explicative formée de la somme des valeurs de x1 et x2.

Le package broom offre des fonctions pour faciliter la manipulation de sorties d’une fonction d’ajustement de modèle. En structurant vos données et en utilisant les outils du tidyverse, vous gagnez non seulement en lisibilité, mais aussi en robustesse pour l'ensemble de vos analyses statistiques complexes.

tags: #faire #des #cumuls #de #recolte #sur