« Manipuler des données avec dplyr » : différence entre les versions
mAucun résumé des modifications |
|||
Ligne 309 : | Ligne 309 : | ||
==== Sélectionner des variables/colonnes en utilisant des filtres composites ==== | ==== Sélectionner des variables/colonnes en utilisant des filtres composites ==== | ||
On peut produire des sélections plus complexes en utilisant des fonctions que '''dplyr''' met à disposition. Ces fonctions peuvent être d'ailleurs combinés avec les opérateurs logiques : | |||
* <code>&</code> : AND | |||
* <code>|</code> : OR | |||
Voici un exemple qui utilise les fonctions <code>starts_with(...)</code> et <code>ends_with</code> pour définir les critères de sélection : | |||
<source lang="R"> | |||
# Utiliser des fonctions dans les critères de sélection | |||
gapminder %>% | |||
select(starts_with("c") | ends_with("xp")) # Sélectionne country, continent et lifeExp | |||
gapminder %>% | |||
select(starts_with("c") & ends_with("t")) # Sélectionne seulement continent | |||
</source> |
Version du 1 septembre 2021 à 20:43
Introduction
dplyr est un paquet de R faisant partie de l'écosystème Tidyverse utile pour manipuler des données en format rectangulaire (i.e. lignes et colonnes). Il utilise une grammaire basée sur les actions les plus fréquentes dans la manipulations des données comme par exemple filtrer, agréger, sélectionner, transformer, etc. Le paquet dplyr peut être utilisé dans plusieurs contextes, comme par exemple :
- le nettoyage des données brutes importées avec R
- l'agrégation de données depuis une ou plusieurs sources
- interroger les données à travers des filtres complexes
- l'organisation de données pour l'affichage dans des reports, pages web, etc.
- la mise en forme de données pour visualisation des données avec R, notamment en combinaison avec le paquet ggplot2.
Cet article propose un survol des manipulations les plus fréquentes, ainsi que des ressources complémentaires.
Prérequis
L'article nécessite de connaissances de base de R, notamment au niveau des structures de données de type data.frame
ou tibble
(i.e. organisées en lignes et colonnes). La lecture préalable de l'article Introduction à Tidyverse est également recommandée.
Installation et chargement
dplyr est l'un des paquets qui composent l'écosystème Tidyverse. Il peut donc être installé deux deux manières :
- Paquet individuel
- Paquet global Tidyverse
Paquet dplyr individuel
Pour installer seulement le paquet dplyr, la commande est la suivante :
# Installation individuelle
install.packages("dplyr")
Pour utiliser le paquet il faudra à ce moment le charger :
library(dplyr)
Paquet global Tidyverse
Si vous installez le paquet global Tidyverse, dplyr est installé automatiquement.
# Installation de Tidyverse
install.packages("tidyverse")
L'installation de l'écosystème Tidyverse est conseillée, car dplyr peut s'intégrer facilement avec d'autres manipulations sur les données comme par exemple la visualisation des données avec ggplot2.
Pour utiliser le paquet vous pouvez à ce moment choisir si :
- Charger seulement dplyr
library(dplyr)
- Charger tous les paquets de Tidyverse
library(tidyverse)
Voir Introduction à Tidyverse pour plus de détails.
Données gapminder utilisées dans le tutoriel
Pour faciliter la compréhension des différents éléments de dplyr, cet article utilise un jeu de données issue du paquet gapminder (Bryan, 2017), créé par Jennifer Bryan, qui est un extrait des données collectées par la fondation Gapminder, un institution indépendante qui utilise les données afin de modifier des mauvaises conceptions que les personnes ont souvent à propos de phénomènes globaux.
Cette section explique comment installer le paquet et fourni une description des donnée disponibles. Au moment de l'écriture de ce tutoriel, la version du paquet gapminder est la 0.3.0
(voir versionnage sémantique). Le paquet propose des données sur plusieurs nations du monde. À la version 0.3.0, les données sont disponibles jusqu'en 2007.
Installation et chargement
Pour disposer des données, il faut d'abord installer le paquet avec la commande :
install.packages("gapminder")
À ce moment, il faut charger le paquet pour pouvoir l'utiliser
library(gapminder)
Description des données
Une fois chargé le paquet avec l'instruction library(gapminder)
vous aurez accès à deux références symboliques :
gapminder
gapminder_unfiltered
Les deux jeux de données ont la même structure, mais gapminder
compte seulement 1'704 observations, tandis que gapminder_unfiltered en a 3'313. Nous allons utiliser gapminder
dans la suite de cet article.
Avec la commande str(gapminder)
on peut accéder à des informations sur le jeu de données :
tibble[,6] [1,704 x 6] (S3: tbl_df/tbl/data.frame)
$ country : Factor w/ 142 levels "Afghanistan",..: 1 1 1 1 1 1 1 1 1 1 ...
$ continent: Factor w/ 5 levels "Africa","Americas",..: 3 3 3 3 3 3 3 3 3 3 ...
$ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
$ lifeExp : num [1:1704] 28.8 30.3 32 34 36.1 ...
$ pop : int [1:1704] 8425333 9240934 10267083 11537966 13079460 14880372 12881816 13867957 16317921 22227415 ...
$ gdpPercap: num [1:1704] 779 821 853 836 740 ...
Avec la fonction glimpse(gapminder)
on peut implémenter la structure avec un aperçu des données contenues :
Rows: 1,704
Columns: 6
$ country <fct> "Afghanistan", "Afghanistan", "Afghanistan", "Afghanistan", "Afghanista~
$ continent <fct> Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia, Asia,~
$ year <int> 1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007,~
$ lifeExp <dbl> 28.801, 30.332, 31.997, 34.020, 36.088, 38.438, 39.854, 40.822, 41.674,~
$ pop <int> 8425333, 9240934, 10267083, 11537966, 13079460, 14880372, 12881816, 138~
$ gdpPercap <dbl> 779.4453, 820.8530, 853.1007, 836.1971, 739.9811, 786.1134, 978.0114, 8~
Si vous utilisez RStudio, vous pouvez voir directement les données en format spreadsheet avec l'instruction View(gapminder)
.
Ces commandes nous permettent de découvrir que le jeu de données gapminder
est organisé dans un format long (voir la section Tidy data de l'Introduction à Tidyverse), avec 6 variables et 1'704 observations. En combinant des informations issues des commandes précédentes, ainsi que depuis la documentation du paquet, on découvre les informations suivantes à propos des six variables du jeu de données :
country
: le nom de la nation, un facteur avec 142 modalités, c'est-à-dire 142 nations différentes. La documentation suggère que pour chaque nation, il y existe 12 observations (i.e. lignes) avec les données recueillies depuis 1952 à 2007, avec des intervalles fixes de 5 ans. On peut récupérer les noms des nations avec la commandelevels(gapminder$country)
continent
: le nom du continent dans lequel se trouve la nation, un facteur avec 5 modalités, donc les 5 continents Africa, America, Asia, Europe, Oceania. On peut récupérer les noms des facteurs avec la commandelevels(gapminder$continent)
year
: l'année de référence. Comme indiqué plus haut, les données couvrent la période entre 1951 et 2007, avec 5 années d'intervalles. On peut récupérer les différentes années avec la commandeunique(gapminder$year)
(car il s'agit de chiffres et pas d'un facteur comme les variables précédentes).lifeExp
: l'espérance de vie à la naissance en annéespop
: la population de la nation à l'année de référencegdpPercap
: le produit intérieur brut en dollar international (Geary-Khamis), une mesure qui ajuste pour la différence au fil du temps. Les détails économiques ne sont pas nécessaires pour suivre le tutoriel, il suffit de retenir que cette variable représente grosso-modo la richesse d'une nation de manière standardisée et donc comparable entre pays et années.
Le paquet met à disposition également une autre référence symbolique, country_codes
: un jeu de données qui contient notamment l’abréviation de la nation (e.g.
FRA, GER, CHE, ...). Nous utiliserons ce deuxième jeu de données pour montrer des opérations qui impliquent deux tableaux. La commande str(country_codes)
affiche la structure suivante :
tibble[,3] [187 x 3] (S3: tbl_df/tbl/data.frame)
$ country : chr [1:187] "Afghanistan" "Albania" "Algeria" "Angola" ...
$ iso_alpha: chr [1:187] "AFG" "ALB" "DZA" "AGO" ...
$ iso_num : int [1:187] 4 8 12 24 32 51 533 36 40 31 ...
Chargement des paquets nécessaires à suivre le tutoriel
Pour suivre le tutoriel, il est donc nécessaire de charger au moins les deux paquets tidyverse (qui incorpore également dplyr) et gapminder. En d'autres termes, il serait bien que votre fichier de script R commence avec les lignes de code suivantes :
library(tidyverse)
library(gapminder)
Le chargement de tidyverse est recommandé, car le tutoriel propose occasionnellement des croisement avec d'autres paquets de l'écosystème Tidyverse pour montrer l'intégration de la manipulation des données avec d'autres opérations utiles.
Notation sur le style de codage utilisé
Ce tutoriel essaie de montrer les aspects les plus relevants du code avec dplyr et pour ce faire essaie de maintenir une certaine consistence dans le style de codage utilisé. Voici quelques indications qui peuvent aider à mieux suivre le code.
Utilisation du pipe
Comme indiqué dans l'introduction à Tidyverse, l'écosystème favorise l'enchaînement séquentiel des manipulations à travers l'opérateur pipe %>%
. L'utilisation de cet opérateur n'est cependant pas indispensable, car les fonctions de dplyr peuvent être utilisé également comme fonction normales. Pour rappel voici deux exemples qui obtiennent les deux seulement les observations relatives à l'année 2002 et les trient en ordre de population ascendante. Le fonctionnement des fonctions spécifiques sera abordés plus bas, pour l'instant l'attention est portée sur la syntaxe :
# Notation "classique"
classique <- arrange(filter(gapminder, year == 2002), pop)
# Notation avec pipe
avec_pipe <- gapminder %>%
filter(year == 2002) %>%
arrange(pop)
# Confirmer que c'est la même chose
identical(classique, avec_pipe) # Donne TRUE
Le résultat de l'évaluation de la dernière ligne sera TRUE
, ce qui confirme que les deux notations obtiennent exactement le même résultat. Cependant, la notation avec pipe est plus simple à lire, surtout si on utilise l'indentation et une opération par ligne, suivi par le pipe.
Pour rappel, le pipe marche selon le principe que le premier argument passé à une fonction est un data.frame ou un tibble, et que chaque fonction retourne exactement le même type d'object. De cette manière, on peut construire des chaines d'instructions comme dans l'example avec notation pipe.
|>
. Si vous préférez cette notation, vous pouvez remplacer le pipe %>%
avec |>
. Utilisation minimaliste de références symboliques
Une autre pratique utilisée dans ce tutoriel est celle d'éviter au maximum de créer des références symboliques pour leur attribuer les résultats d'une manipulation avec dplyr, et d'écrire plutôt des instructions qui sont évaluées directement. L'utilisation de références symboliques sera adopté seulement si elle apporte des avantages, par exemple en termes d'alternatives ou de traitement ultérieur. Voici du code qui explique ce principe :
# Exécution directe, sans référence symbolique
gapminder %>%
filter(year == 2007)
# Attribution à une référence symbolique "data_2007" pour utilisation ultérieur
data_2007 <- gapminder %>%
filter(year == 2007)
# Trier en ordre de population ascendant
data_2007 %>%
arrange(pop)
# trier en ordre de population descendante
data_2007 %>%
arrange(desc(pop))
Manipulations de base sur un tableau
Cette section illustre des manipulations de base qui sont souvent utiles dans le traitement de données comme :
- sélectionner un sous-groupe de variables/colonnes
- filtrer des observations/lignes selon certains critères
- trier les données selon un ordre spécifique
Sélectionner un sous-groupe de variables/colonnes
Le jeu de données gapminder
contient seulement 6 variables/colonnes, mais des jeux de données peuvent prévoir un nombre beaucoup plus conséquent. Il est donc souvent utile, pour pouvoir se concentrer seulement sur les variables d'intérêt, de sélectionner seulement un sous-groupe des colonnes. dplyr permet d'exécuter cette opération à travers la fonction :
select(...)
Cette fonction accepte à son intérieur des arguments qui permettent de déterminer les critères de sélection des variables/colonnes. Voici de suite quelques applications pratiques.
Sélectionner une seule variable/colonne
Pour sélectionner une seule variable/colonne, il suffit de passer le nom de la colonne en argument :
# Sélectionner seulement la variable relative à la population
gapminder %>%
select(pop)
Le nom de la colonne peut également être écrit entre guillemets :
gapminder %>%
select("pop")
Dans les deux cas, l'opération donne une structure de données (de type data.frame ou tibble) et non pas un vecteur, même si on a une seule colonne :
# A tibble: 1,704 x 1
pop
<int>
1 8425333
2 9240934
3 10267083
...
Sélectionner plusieurs variables/colonnes par leurs noms
Pour sélectionner plusieurs variables/colonnes en même temps, on peut simplement passer leurs noms en argument séparées par une virgule :
# Sélectionner trois colonnes selon leurs noms
gapminder %>%
select(country, gdpPercap, continent)
Comme vous pouvez le voir depuis l'exemple, on peut également sélectionner les colonnes dans un ordre différent de celui d'origine (e.g., gdpPercap est sélectionné avant continent). La structure des données qui en résulte mantinent à ce moment l'ordre établi dans les arguments de sélection :
# A tibble: 1,704 x 3
country gdpPercap continent
<fct> <dbl> <fct>
1 Afghanistan 779. Asia
2 Afghanistan 821. Asia
3 Afghanistan 853. Asia
...
Sélectionner plusieurs variables/colonnes adjacentes
Souvent il est utile de sélectionner des sous-groupes de variables/colonnes qui se trouvent l'une à côté de l'autre. À ce moment, il devient rébarbative de les sélectionner toutes par leurs noms individuellement. On peut à ce moment utiliser la notation colonne_initiale:colonne_finale
pour sélectionner toutes les variables qui se trouvent entre les deux, avec les deux colonnes spécifiées qui sont incluses dans la sélection.
# Sélectionner les colonnes entre country et lifeExp (i.e. les 4 premières colonnes)
gapminder %>%
select(country:lifeExp)
Il est possible de combiner plusieurs notations séparées par une virgule :
# Combination avec nom de colonne simple
gapminder %>%
select(country, lifeExp:gdpPercap)
# Combination avec sélections adjacentes
gapminder %>%
select(country:continent, pop:gdpPercap)
Le jeu de données gapminder
contient peu de variables, donc ces notations ne sont pas très utiles, mais elles peuvent être très utiles sur des jeux de données plus larges.
Sélectionner par exclusion de variables/colonnes
Il peut arriver de vouloir sélectionner toutes les variables/colonnes, sauf quelques-unes en particulier. Dans ce cas, on peut spécifier quelles colonnes exclure à travers l'opérateur de négation !
.
# Exclure seulement le continent
gapminder %>%
select(!continent)
Si on veut exclure plusieurs variables en même temps, on peut les grouper dans un vecteur avec la notation !c(colonne1, colonne2, colonne3, ...)
:
# Exclure plusieurs variables par leurs noms
gapminder %>%
select(!c(lifeExp, gdpPercap))
Enfin, on peut combiner la négation également avec des variables adjacentes avec la notation !colonne_initiale:colonne_finale
:
# Exclure les colonnes de lifeExp à gdpPercap
gapminder %>%
select(!lifeExp:gdpPercap)
Sélectionner des variables/colonnes en utilisant des filtres composites
On peut produire des sélections plus complexes en utilisant des fonctions que dplyr met à disposition. Ces fonctions peuvent être d'ailleurs combinés avec les opérateurs logiques :
&
: AND|
: OR
Voici un exemple qui utilise les fonctions starts_with(...)
et ends_with
pour définir les critères de sélection :
# Utiliser des fonctions dans les critères de sélection
gapminder %>%
select(starts_with("c") | ends_with("xp")) # Sélectionne country, continent et lifeExp
gapminder %>%
select(starts_with("c") & ends_with("t")) # Sélectionne seulement continent