Chapitre 6 Manipuler des données dans R
6.1 Introduction
6.1.1 Objectif de ce cours
Le data scientist a très rarement les données structurées dans la forme qui lui convient. Il lui revient de les mettres dans cette forme. De ce fait, il lui est indispensable de savoir manipuler les données. Il s’agit de la maîtrise d’une série de tâches parmi lesquelles nous pouvons citer:
la simple sélection d’un sous-ensemble à l’intérieur d’un large groupe ;
la sélection d’un nombre déterminé de variables (attributs) ;
la combinaison d’informations conservées dans différentes data frame;
la suppresion et la création variables;
la réorganisation des données à l’intérieur d’un data frame.
Dans ce chapitre, nous allons voir quelques techniques de manipulation de données avec deux packages: dplyr
et tidyr
.
6.1.2 Que nous faut-il?
R (évidemment) et RStudio (de préférence) installés sur le poste de travail;
les packages dplyr et tidyr installés;
les fichiers fournis dans le cadre du module.
6.1.3 Données
Nous allons illustrer ce chapitre avec une compilation de données tirées des Recensements Généraux de la Population et de l’Habitat au Mali, menés respectivement en 1976, 1987, 1998 et 2009. Il s’agit:
d’un côté, de tableaux sur la population par groupe d’âge (tranche de 5 ans);
de l’autre, de tableaux sur la population par commune.
6.2 dplyr
: les fonctions de transformation
6.2.1 Aperçu
Le package dplyr
est un package crééé par Hadley Wickham. Il fait partie de l’écosystème tidyverse
qui est un ensemble de packages conçus pour la data science et partageant tous les mêmes philoshophie, grammaire et structure. Nous allons, avec l’exploration des packages du tidyverse
, comprendre l’importance de cette grammaire. Elle traduit la volonté des auteurs de condenser dans le nom des fonctions l’idée de la tâche que celles-ci exécutent. Dans dplyr
, les fonctions majeures sont des verbes (comme nous allons le voir).
Alors, qu’est-ce que dplyr
fait? Voici une simple analogie. Si les données constituent un tissu, nous pouvons voir dplyr
comme à la fois la paire de ciseaux pour en faire la coupe, et l’aiguille et le fil pour le coudre. Pour le prouver, voici le logo associé au package.
Pour travailler avec dplyr
, l’on commence par l’installer sur son poste de travail. Etant intégré au tidyverse
, il est possible de l’installer en même temps que les autres composantes de celui-ci.
install.packages("tidyverse")
L’on peut aussi l’installer tout seul.
install.packages("dplyr")
Cette commande télécharge depuis le réseau d’archivage des packages R la dernière version stable publiée. Toutefois, il est aussi possible d’acquérir les versions en développement depuis Github.
install.packages("devtools") # au cas où ce package n'est pas installé
devtools::install_github("tidyverse/dplyr")
Une fois l’installation effectuée, l’on peut charger le package.
library(dplyr)
6.2.2 Avant d’aller loin
Avant d’aller loin, il est utile d’introduire la notion de tibble qui est une partie intégrante des packages du tidyverse
. Il s’agit de la même chose que le data frame, mais celui-ci repensé. Le tibble n’altère pas la structure ni la classe des données contenue dans un data frame. Par contre, il agit sur l’affichage des données et, comme nous le verrons plus tard, leur permet de stocker de nouvelles sortes de données (colonne-list
, à noter quelque part…on y reviendra). Pour l’instant regardons-le à l’oeuvre en termes d’affichage.
Prenons les données sur les populations des communes du Mali en 2009 (RGPH, 2009).
# Importation des données
adm3_pop_2009 <- read.csv("https://raw.githubusercontent.com/fousseynoubah/dswr_slides/master/5_Manipuler_Donnees_dans_R/data/adm3_pop_2009.csv")
Quelle est la classe de cet objet?
class(adm3_pop_2009)
## [1] "data.frame"
C’est un data frame! Regardons sa structure ainsi que les six premières observations
str(adm3_pop_2009)
## 'data.frame': 703 obs. of 9 variables:
## $ id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ admin0_nom: Factor w/ 1 level "Mali": 1 1 1 1 1 1 1 1 1 1 ...
## $ admin1_nom: Factor w/ 9 levels "Bamako","Gao",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ admin2_nom: Factor w/ 50 levels "Abeibara","Ansongo",..: 23 23 23 23 23 23 23 23 23 23 ...
## $ admin3_nom: Factor w/ 687 levels "Abeibara","Adarmalane",..: 25 74 116 156 192 210 231 238 249 257 ...
## $ annee : int 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 ...
## $ homme : num 6123 6144 7115 11466 5141 ...
## $ femme : int 5974 6353 7015 12091 5017 1934 3927 1903 10234 3445 ...
## $ source : Factor w/ 1 level "RGPH": 1 1 1 1 1 1 1 1 1 1 ...
head(adm3_pop_2009)
## id admin0_nom admin1_nom admin2_nom admin3_nom annee homme femme source
## 1 1 Mali Kayes Kayes Bangassi 2009 6123 5974 RGPH
## 2 2 Mali Kayes Kayes Colimbine 2009 6144 6353 RGPH
## 3 3 Mali Kayes Kayes Diamou 2009 7115 7015 RGPH
## 4 4 Mali Kayes Kayes Djelebou 2009 11466 12091 RGPH
## 5 5 Mali Kayes Kayes Faleme 2009 5141 5017 RGPH
## 6 6 Mali Kayes Kayes Fegui 2009 1999 1934 RGPH
Maintenant, déclarons cet objet comme un tibble.
adm3_pop_2009 <- as_tibble(adm3_pop_2009)
Revoyons la classe.
class(adm3_pop_2009)
## [1] "tbl_df" "tbl" "data.frame"
La classe a changé, ou plutôt elle s’est consolidée. De nouvelles caractéristiques ont été ajoutées à data.frame
. Maintenant, imprimons le jeu de données lui-même.
adm3_pop_2009
## # A tibble: 703 x 9
## id admin0_nom admin1_nom admin2_nom admin3_nom annee homme femme
## <int> <fct> <fct> <fct> <fct> <int> <dbl> <int>
## 1 1 Mali Kayes Kayes Bangassi 2009 6123 5974
## 2 2 Mali Kayes Kayes Colimbine 2009 6144 6353
## 3 3 Mali Kayes Kayes Diamou 2009 7115 7015
## 4 4 Mali Kayes Kayes Djelebou 2009 11466 12091
## 5 5 Mali Kayes Kayes Faleme 2009 5141 5017
## 6 6 Mali Kayes Kayes Fegui 2009 1999 1934
## 7 7 Mali Kayes Kayes Gory Gope~ 2009 3939 3927
## 8 8 Mali Kayes Kayes Goumera 2009 1918 1903
## 9 9 Mali Kayes Kayes Guidimaka~ 2009 9798 10234
## 10 10 Mali Kayes Kayes Hawa Demb~ 2009 3406 3445
## # ... with 693 more rows, and 1 more variable: source <fct>
Avec les tibble, l’affichage d’un jeu de donnée donne par défaut les dix premières observations et indique la classe et/ou le type des colonnes. Nous voyons par exemple que la variable id
est composée d’entiers tandis que la variable admin0_nom
est déclarée en facteur. De ce fait, l’impression d’un tibble permet de combiner les résultats qu’on obtiendrait avec les commandes str
et head
.
Le tibble est l’output par défaut des fonctions du tidyverse
. Reprenons l’opération d’importation. Cette fois-ci, au lieu de passer par read.csv
qui est une fonction basique, nous utiliserons read_csv
du package readr
, lui-même membre du club tidyverse
.
# Chargement du package "readr"
library(readr)
# Importation des données
adm3_pop_2009 <- read_csv("https://raw.githubusercontent.com/fousseynoubah/dswr_slides/master/5_Manipuler_Donnees_dans_R/data/adm3_pop_2009.csv")
## Parsed with column specification:
## cols(
## id = col_double(),
## admin0_nom = col_character(),
## admin1_nom = col_character(),
## admin2_nom = col_character(),
## admin3_nom = col_character(),
## annee = col_double(),
## homme = col_double(),
## femme = col_double(),
## source = col_character()
## )
# Classe
class(adm3_pop_2009)
## [1] "spec_tbl_df" "tbl_df" "tbl" "data.frame"
# Impression
adm3_pop_2009
## # A tibble: 703 x 9
## id admin0_nom admin1_nom admin2_nom admin3_nom annee homme femme
## <dbl> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 1 Mali Kayes Kayes Bangassi 2009 6123 5974
## 2 2 Mali Kayes Kayes Colimbine 2009 6144 6353
## 3 3 Mali Kayes Kayes Diamou 2009 7115 7015
## 4 4 Mali Kayes Kayes Djelebou 2009 11466 12091
## 5 5 Mali Kayes Kayes Faleme 2009 5141 5017
## 6 6 Mali Kayes Kayes Fegui 2009 1999 1934
## 7 7 Mali Kayes Kayes Gory Gope~ 2009 3939 3927
## 8 8 Mali Kayes Kayes Goumera 2009 1918 1903
## 9 9 Mali Kayes Kayes Guidimaka~ 2009 9798 10234
## 10 10 Mali Kayes Kayes Hawa Demb~ 2009 3406 3445
## # ... with 693 more rows, and 1 more variable: source <chr>
Vous voyez!
Même si l’on passe un data frame à une fonction du tidyverse
, le résultat est un tibble. Prenons la fonction glimpse
du package dplyr
(notez que glimpse veut dire aperçu en anglais).
# Importation des données
adm3_pop_2009 <- read.csv("https://raw.githubusercontent.com/fousseynoubah/dswr_slides/master/5_Manipuler_Donnees_dans_R/data/adm3_pop_2009.csv")
# Aperçu avec "glimpse"
glimpse(adm3_pop_2009)
## Observations: 703
## Variables: 9
## $ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...
## $ admin0_nom <fct> Mali, Mali, Mali, Mali, Mali, Mali, Mali, Mali, Mal...
## $ admin1_nom <fct> Kayes, Kayes, Kayes, Kayes, Kayes, Kayes, Kayes, Ka...
## $ admin2_nom <fct> Kayes, Kayes, Kayes, Kayes, Kayes, Kayes, Kayes, Ka...
## $ admin3_nom <fct> Bangassi, Colimbine, Diamou, Djelebou, Faleme, Fegu...
## $ annee <int> 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 200...
## $ homme <dbl> 6123, 6144, 7115, 11466, 5141, 1999, 3939, 1918, 97...
## $ femme <int> 5974, 6353, 7015, 12091, 5017, 1934, 3927, 1903, 10...
## $ source <fct> RGPH, RGPH, RGPH, RGPH, RGPH, RGPH, RGPH, RGPH, RGP...
# Comparons à "str"
str(adm3_pop_2009)
## 'data.frame': 703 obs. of 9 variables:
## $ id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ admin0_nom: Factor w/ 1 level "Mali": 1 1 1 1 1 1 1 1 1 1 ...
## $ admin1_nom: Factor w/ 9 levels "Bamako","Gao",..: 3 3 3 3 3 3 3 3 3 3 ...
## $ admin2_nom: Factor w/ 50 levels "Abeibara","Ansongo",..: 23 23 23 23 23 23 23 23 23 23 ...
## $ admin3_nom: Factor w/ 687 levels "Abeibara","Adarmalane",..: 25 74 116 156 192 210 231 238 249 257 ...
## $ annee : int 2009 2009 2009 2009 2009 2009 2009 2009 2009 2009 ...
## $ homme : num 6123 6144 7115 11466 5141 ...
## $ femme : int 5974 6353 7015 12091 5017 1934 3927 1903 10234 3445 ...
## $ source : Factor w/ 1 level "RGPH": 1 1 1 1 1 1 1 1 1 1 ...
Nous voyons que glimpse
répartit différemment l’espace en les observations affichées. Il se préoccupe plus de l’équilibre entre celles-ci que les fonctions comme str
ou head
.
Nous allons maintenant explorer les verbes majeurs du package dplyr
. Dans une démarche pédagogique - pour rappeler les bases déjà vue et enrichir celles-ci, au besoin - nous tenterons autant que possible de reproduire les exemples avec R-base aussi afin de mettre en exergue les différences.
6.2.3 Selection et/ou exclusion de variables: select
Comme nous avons vu précédemment, il arrive souvent que l’on veuille sélectionner certaines variables d’un jeu de données. Dans notre cas, supposons que nous sommes seulement intéressés par les chiffres. Il s’agit des colonnes: homme
et femme
.
Ramenons notre jeu de données.
# Chargement du package "readr"
library(readr)
# Importation des données
adm3_pop_2009 <- read_csv("https://raw.githubusercontent.com/fousseynoubah/dswr_slides/master/5_Manipuler_Donnees_dans_R/data/adm3_pop_2009.csv")
## Parsed with column specification:
## cols(
## id = col_double(),
## admin0_nom = col_character(),
## admin1_nom = col_character(),
## admin2_nom = col_character(),
## admin3_nom = col_character(),
## annee = col_double(),
## homme = col_double(),
## femme = col_double(),
## source = col_character()
## )
# Impression
adm3_pop_2009
## # A tibble: 703 x 9
## id admin0_nom admin1_nom admin2_nom admin3_nom annee homme femme
## <dbl> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 1 Mali Kayes Kayes Bangassi 2009 6123 5974
## 2 2 Mali Kayes Kayes Colimbine 2009 6144 6353
## 3 3 Mali Kayes Kayes Diamou 2009 7115 7015
## 4 4 Mali Kayes Kayes Djelebou 2009 11466 12091
## 5 5 Mali Kayes Kayes Faleme 2009 5141 5017
## 6 6 Mali Kayes Kayes Fegui 2009 1999 1934
## 7 7 Mali Kayes Kayes Gory Gope~ 2009 3939 3927
## 8 8 Mali Kayes Kayes Goumera 2009 1918 1903
## 9 9 Mali Kayes Kayes Guidimaka~ 2009 9798 10234
## 10 10 Mali Kayes Kayes Hawa Demb~ 2009 3406 3445
## # ... with 693 more rows, and 1 more variable: source <chr>
Maintenant, passons d’abord par les méthodes de R-base, comme nous avons vu avant.
adm3_pop_2009[ , c("homme", "femme")]
## # A tibble: 703 x 2
## homme femme
## <dbl> <dbl>
## 1 6123 5974
## 2 6144 6353
## 3 7115 7015
## 4 11466 12091
## 5 5141 5017
## 6 1999 1934
## 7 3939 3927
## 8 1918 1903
## 9 9798 10234
## 10 3406 3445
## # ... with 693 more rows
ou
subset(x = adm3_pop_2009, select = c(homme, femme))
## # A tibble: 703 x 2
## homme femme
## <dbl> <dbl>
## 1 6123 5974
## 2 6144 6353
## 3 7115 7015
## 4 11466 12091
## 5 5141 5017
## 6 1999 1934
## 7 3939 3927
## 8 1918 1903
## 9 9798 10234
## 10 3406 3445
## # ... with 693 more rows
Dans dplyr
, l’on utilise pour ce faire la fonction select
qui va se rapprocher de la fonction subset
de R-base.
select(adm3_pop_2009, homme, femme)
## # A tibble: 703 x 2
## homme femme
## <dbl> <dbl>
## 1 6123 5974
## 2 6144 6353
## 3 7115 7015
## 4 11466 12091
## 5 5141 5017
## 6 1999 1934
## 7 3939 3927
## 8 1918 1903
## 9 9798 10234
## 10 3406 3445
## # ... with 693 more rows
Le premier argument de la fonction est le jeu de données. Ceci est général pour toutes les fonctions de dplyr
. Ensuite viennent les autres arguments. Ici, nous avons énuméré les variables qui nous intéressent. La fonction select
présente un grande simplicité par rapport aux alternatives de R-base. A l’instar de subset
, elle ne requiert pas que les noms de variables soient entre griffes (" "
). Aussi, elle ne requiert pas que l’on spécifie le nombre d’observations à afficher, que l’input soit un data frame ou un tibble. Avec les fonctions de R-base, quand l’input est une tibble, l’affichage est limité à dix observations. Toutefois, cette règle est violée quand l’input est un data frame.
Il y a un autre avantage avec select
, mais qui est commun au tidyverse
tout entier. C’est l’opérateur: %>%
que l’on appelle pipe opérator. Ce signe permet d’ordonner les lignes de commandes de sorte à rendre compte du séquençage des opérations. Nous savons ici que nous partons d’un jeu de données, adm3_pop_2009
, que nous soumettons à une opération. Avec %>%
, nous verbalisons cette idée en faisant de l’input de départ la première ligne.
adm3_pop_2009 %>%
select(homme, femme)
## # A tibble: 703 x 2
## homme femme
## <dbl> <dbl>
## 1 6123 5974
## 2 6144 6353
## 3 7115 7015
## 4 11466 12091
## 5 5141 5017
## 6 1999 1934
## 7 3939 3927
## 8 1918 1903
## 9 9798 10234
## 10 3406 3445
## # ... with 693 more rows
Avec cette nouvelle écriture, nous obtenons la même résultat, mais la lisibilité est améliorée. A partir de maintenant, nous allons progressivement adoptée cette façon d’écrire les opérations.
Un autre avantage de select
est de permettre la sélection de plusieurs variables à travers leur communalité. Dans notre jeu, nous avons trois variables qui portent toutes le terme admin
comme préfixe. Plutôt que de les sélectionner une à une nous pouvons les appeler toutes ensembles. Commençons par R-base.
names_df <- names(adm3_pop_2009)
select_df <- startsWith(x = names_df, prefix = "adm")
adm3_pop_2009[, select_df]
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
Cette opération nous a pris trois lignes différents. Avec select
, nous en faisons juste de deux lignes séquencées (même une si l’on veut).
adm3_pop_2009 %>%
select(starts_with("adm"))
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
L’on peut faire la même chose avec les suffixes…
adm3_pop_2009 %>%
select(ends_with("nom"))
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
…ou chercher des termes indépendemment de leur position dans le nom des variables.
adm3_pop_2009 %>%
select(contains("nom"))
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
dplyr
contient une variétés de fonctions similaires dont: matches()
, num_range()
, one_of()
, everything()
, group_cols()
. Avec R, l’on peut aboutir au même résultat en utilisant différentes méthodes. La force de dplyr
- et de tidyverse
dans une large mesure - est que la méthode est plus économe en écriture de codes et le séquençage bien explicité à l’aide de l’opérateur %>%
.
La sélection peut aussi se faire sur la base de l’index des colonnes, c’est-à-dire leur position. Sélectionnons de la deuxième à la cinquième colonne.
# Avec R-base
adm3_pop_2009[, c(2:5)]
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
# Avec dpylr
adm3_pop_2009 %>%
select(2:5)
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
La même chose peut se faire avec le nom des variables.
# Avec R-base
adm3_pop_2009[, c("admin0_nom", "admin1_nom", "admin2_nom", "admin3_nom")]
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
# Avec dplyr
adm3_pop_2009 %>%
select(admin0_nom, admin1_nom, admin2_nom, admin3_nom)
## # A tibble: 703 x 4
## admin0_nom admin1_nom admin2_nom admin3_nom
## <chr> <chr> <chr> <chr>
## 1 Mali Kayes Kayes Bangassi
## 2 Mali Kayes Kayes Colimbine
## 3 Mali Kayes Kayes Diamou
## 4 Mali Kayes Kayes Djelebou
## 5 Mali Kayes Kayes Faleme
## 6 Mali Kayes Kayes Fegui
## 7 Mali Kayes Kayes Gory Gopela
## 8 Mali Kayes Kayes Goumera
## 9 Mali Kayes Kayes Guidimakan Keri Kaff
## 10 Mali Kayes Kayes Hawa Dembaya
## # ... with 693 more rows
L’on peut faire plus simple avec dplyr
quand les variables recherchées se suivent.
adm3_pop_2009 %>%
select(admin0_nom:admin3_nom)
Comme avec R-base, la sélection peut aussi se faire sur la base de l’exclusion. Imaginez que l’on souhaite exclure les quatre premières variables.
# Avec R-base
adm3_pop_2009[, -c(1:4)]
## # A tibble: 703 x 5
## admin3_nom annee homme femme source
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 Bangassi 2009 6123 5974 RGPH
## 2 Colimbine 2009 6144 6353 RGPH
## 3 Diamou 2009 7115 7015 RGPH
## 4 Djelebou 2009 11466 12091 RGPH
## 5 Faleme 2009 5141 5017 RGPH
## 6 Fegui 2009 1999 1934 RGPH
## 7 Gory Gopela 2009 3939 3927 RGPH
## 8 Goumera 2009 1918 1903 RGPH
## 9 Guidimakan Keri Kaff 2009 9798 10234 RGPH
## 10 Hawa Dembaya 2009 3406 3445 RGPH
## # ... with 693 more rows
# Avec dplyr
adm3_pop_2009 %>%
select(-c(1:4))
## # A tibble: 703 x 5
## admin3_nom annee homme femme source
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 Bangassi 2009 6123 5974 RGPH
## 2 Colimbine 2009 6144 6353 RGPH
## 3 Diamou 2009 7115 7015 RGPH
## 4 Djelebou 2009 11466 12091 RGPH
## 5 Faleme 2009 5141 5017 RGPH
## 6 Fegui 2009 1999 1934 RGPH
## 7 Gory Gopela 2009 3939 3927 RGPH
## 8 Goumera 2009 1918 1903 RGPH
## 9 Guidimakan Keri Kaff 2009 9798 10234 RGPH
## 10 Hawa Dembaya 2009 3406 3445 RGPH
## # ... with 693 more rows
L’on voit qu’à l’instar de R-base, l’on a juste à précédéer les éléments à exclure du signe -
.
6.2.4 Création de variable de variables: mutate
La sélection et la suppression de variables peuvent s’inscrire dans le cadre d’une stratégie d’exploration plus large qui peut elle-même impliquer la création de nouvelles variables.
Revenons à l’exploration de la supériorité numérique entre hommes et femmes, sujet que nous avons abordé dans le chapitre précédent. Supposons que nous souhaitions:
sélectionner les populations pour les hommes et les femmes pour chaque commune;
calculer un ratio
femme
/homme
pour chaque commune.
Avec R-base.
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable
pop_df$ratio <- pop_df$femme / pop_df$homme
# Aperçu
pop_df
## # A tibble: 703 x 4
## admin3_nom homme femme ratio
## <chr> <dbl> <dbl> <dbl>
## 1 Bangassi 6123 5974 0.976
## 2 Colimbine 6144 6353 1.03
## 3 Diamou 7115 7015 0.986
## 4 Djelebou 11466 12091 1.05
## 5 Faleme 5141 5017 0.976
## 6 Fegui 1999 1934 0.967
## 7 Gory Gopela 3939 3927 0.997
## 8 Goumera 1918 1903 0.992
## 9 Guidimakan Keri Kaff 9798 10234 1.04
## 10 Hawa Dembaya 3406 3445 1.01
## # ... with 693 more rows
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(ratio = homme/femme)
## # A tibble: 703 x 4
## admin3_nom homme femme ratio
## <chr> <dbl> <dbl> <dbl>
## 1 Bangassi 6123 5974 1.02
## 2 Colimbine 6144 6353 0.967
## 3 Diamou 7115 7015 1.01
## 4 Djelebou 11466 12091 0.948
## 5 Faleme 5141 5017 1.02
## 6 Fegui 1999 1934 1.03
## 7 Gory Gopela 3939 3927 1.00
## 8 Goumera 1918 1903 1.01
## 9 Guidimakan Keri Kaff 9798 10234 0.957
## 10 Hawa Dembaya 3406 3445 0.989
## # ... with 693 more rows
Le résultat est le même, mais le gain avec dplyr est visible. Le séquençage rend la lecture du code facile. Il évite aussi la création d’un objet intermédiaire, comme ce fut le cas de pop_df
avec R-base.
Dans le cadre précédent, la variable était numérique. Elle peut aussi prendre la forme catégorielle. Considérons par exemple des intervalles de population qu’on souhaiterait créer pour séparer les communes en catégories. Nous allons d’abord faire la somme des deux groupes, hommes et femmes, et ensuite créer la variable catégorielle.
Avec R-base
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Création d'une nouvelle variable: catégorielle
pop_df$pop_cat <- ifelse(pop_df$total < 10000, "<10000", ">=10000")
# Aperçu
pop_df
## # A tibble: 703 x 5
## admin3_nom homme femme total pop_cat
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 Bangassi 6123 5974 12097 >=10000
## 2 Colimbine 6144 6353 12497 >=10000
## 3 Diamou 7115 7015 14130 >=10000
## 4 Djelebou 11466 12091 23557 >=10000
## 5 Faleme 5141 5017 10158 >=10000
## 6 Fegui 1999 1934 3933 <10000
## 7 Gory Gopela 3939 3927 7866 <10000
## 8 Goumera 1918 1903 3821 <10000
## 9 Guidimakan Keri Kaff 9798 10234 20032 >=10000
## 10 Hawa Dembaya 3406 3445 6851 <10000
## # ... with 693 more rows
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable: numérique
mutate(total = homme + femme) %>%
# Création d'une nouvelle variable: catégorielle
mutate(pop_cat = ifelse(total < 10000, "<10000", ">=10000"))
## # A tibble: 703 x 5
## admin3_nom homme femme total pop_cat
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 Bangassi 6123 5974 12097 >=10000
## 2 Colimbine 6144 6353 12497 >=10000
## 3 Diamou 7115 7015 14130 >=10000
## 4 Djelebou 11466 12091 23557 >=10000
## 5 Faleme 5141 5017 10158 >=10000
## 6 Fegui 1999 1934 3933 <10000
## 7 Gory Gopela 3939 3927 7866 <10000
## 8 Goumera 1918 1903 3821 <10000
## 9 Guidimakan Keri Kaff 9798 10234 20032 >=10000
## 10 Hawa Dembaya 3406 3445 6851 <10000
## # ... with 693 more rows
Les deux opérations de création peuvent être rassemblées à l’intérieur d’un seul appel de la fonction mutate
.
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création de deux nouvelles variables: numérique et catégorielle
mutate(total = homme + femme,
pop_cat = ifelse(total < 10000, "<10000", ">=10000"))
## # A tibble: 703 x 5
## admin3_nom homme femme total pop_cat
## <chr> <dbl> <dbl> <dbl> <chr>
## 1 Bangassi 6123 5974 12097 >=10000
## 2 Colimbine 6144 6353 12497 >=10000
## 3 Diamou 7115 7015 14130 >=10000
## 4 Djelebou 11466 12091 23557 >=10000
## 5 Faleme 5141 5017 10158 >=10000
## 6 Fegui 1999 1934 3933 <10000
## 7 Gory Gopela 3939 3927 7866 <10000
## 8 Goumera 1918 1903 3821 <10000
## 9 Guidimakan Keri Kaff 9798 10234 20032 >=10000
## 10 Hawa Dembaya 3406 3445 6851 <10000
## # ... with 693 more rows
L’appel de mutate
n’a pas à être spécifique à une seule variable. La fonction peut effectuer plusieurs opérations lors d’un seul appel.
Une variante de la fonction mutate
est la fonction transmute
. Pendant que la première préserve les variables préexistantes à l’opération de création de nouvelles colonnes, la seconde, quant à elle, les supprime. Reprenons le dernier exemple.
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création de deux nouvelles variables: numérique et catégorielle
transmute(total = homme + femme,
pop_cat = ifelse(total < 10000, "<10000", ">=10000"))
## # A tibble: 703 x 2
## total pop_cat
## <dbl> <chr>
## 1 12097 >=10000
## 2 12497 >=10000
## 3 14130 >=10000
## 4 23557 >=10000
## 5 10158 >=10000
## 6 3933 <10000
## 7 7866 <10000
## 8 3821 <10000
## 9 20032 >=10000
## 10 6851 <10000
## # ... with 693 more rows
Vous voyez! Comme résultat, nous avons les deux nouvelles colonnes. Toutes les autres ont été omises. Toutefois, le nombre d’observations n’a pas varié.
Les avantages de dplyr
deviennent évident avec l’augmentation du nombre d’opérations à mener sur une intrant donnée, très généralement un jeu de données rectangulaires (data frame ou tibble).
6.2.5 Sélection d’observations: filter
Dans le chapitre précédent, nous avions quelques techniques de sélections d’observations. Souvent à partir de la position, souvent à partir de critères définis. Re-appliquons certaines de ces techniques à nos données et comparons à la démarche de dplyr
.
Regardons à nouveau notre jeu de données.
glimpse(adm3_pop_2009)
## Observations: 703
## Variables: 9
## $ id <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ...
## $ admin0_nom <chr> "Mali", "Mali", "Mali", "Mali", "Mali", "Mali", "Ma...
## $ admin1_nom <chr> "Kayes", "Kayes", "Kayes", "Kayes", "Kayes", "Kayes...
## $ admin2_nom <chr> "Kayes", "Kayes", "Kayes", "Kayes", "Kayes", "Kayes...
## $ admin3_nom <chr> "Bangassi", "Colimbine", "Diamou", "Djelebou", "Fal...
## $ annee <dbl> 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 200...
## $ homme <dbl> 6123, 6144, 7115, 11466, 5141, 1999, 3939, 1918, 97...
## $ femme <dbl> 5974, 6353, 7015, 12091, 5017, 1934, 3927, 1903, 10...
## $ source <chr> "RGPH", "RGPH", "RGPH", "RGPH", "RGPH", "RGPH", "RG...
Nous avons 703 observations, donc 703 communes. Regardons les plus grandes en matière de population. Disons, celles qui sont au dessus du seuil de 100000 habitants.
Avec R-base.
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection: valeurs logiques (TRUE/FALSE)
pop_100000_plus <- pop_df$total > 100000
# Mise en oeuvre de la sélection
pop_df[pop_100000_plus, ]
## # A tibble: 12 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Kayes Commune 65135 61184 126319
## 2 Kalabancoro 81018 80864 161882
## 3 Koutiala Commune 70905 70539 141444
## 4 Sikasso Commune 114171 112447 226618
## 5 Segou Commune 66819 66682 133501
## 6 Mopti Commune 60080 60706 120786
## 7 Commune I 168308 166587 334895
## 8 Commune II 78690 80670 159360
## 9 Commune III 63792 64874 128666
## 10 Commune IV 152153 152373 304526
## 11 Commune V 206749 206517 413266
## 12 Commune VI 237951 231702 469653
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(total > 100000)
## # A tibble: 12 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Kayes Commune 65135 61184 126319
## 2 Kalabancoro 81018 80864 161882
## 3 Koutiala Commune 70905 70539 141444
## 4 Sikasso Commune 114171 112447 226618
## 5 Segou Commune 66819 66682 133501
## 6 Mopti Commune 60080 60706 120786
## 7 Commune I 168308 166587 334895
## 8 Commune II 78690 80670 159360
## 9 Commune III 63792 64874 128666
## 10 Commune IV 152153 152373 304526
## 11 Commune V 206749 206517 413266
## 12 Commune VI 237951 231702 469653
Là aussi, nous voyons que la séquence est plus économe.
La sélection peut aussi porter sur des variables en caractères ou catégorielles. Supposons que nous souhaitons connaître la population d’une commune dont nous avons le nom: Bambara Maoudé.
Avec R-base
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection: valeurs logiques (TRUE/FALSE)
bambara_maoude <- pop_df$admin3_nom == "Bambara Maoude"
# Mise en oeuvre de la sélection
pop_df[bambara_maoude, ]
## # A tibble: 1 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Bambara Maoude 8315 8170 16485
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(admin3_nom == "Bambara Maoude")
## # A tibble: 1 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Bambara Maoude 8315 8170 16485
Dans le chapitre précédent, nous avons qu’en matière de sélection d’observations à partir de critères, il y a plusieurs façons de combiner ces derniers. On peut les ajouter avec le signe &
, les présenter comme des alternatives avec le signe |
ou opérer avec une logique de négation avec le signe !
. Avec dplyr
, ces signes demeurent valides.
Supposons que nous voulons connaître les communes de plus de 100000 où il y a plus de femmes que d’hommes. Ici, les deux critères s’accumulent.
Avec R-base.
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
pop_100000_plus <- pop_df$total > 100000
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
femmes_sup_hommes <- pop_df$femme > pop_df$homme
# Mise en oeuvre de la sélection
pop_df[pop_100000_plus & femmes_sup_hommes, ]
## # A tibble: 4 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Mopti Commune 60080 60706 120786
## 2 Commune II 78690 80670 159360
## 3 Commune III 63792 64874 128666
## 4 Commune IV 152153 152373 304526
Avec dplyr
.
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000,
# Critère 2: femme > homme
femme > homme
)
## # A tibble: 4 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Mopti Commune 60080 60706 120786
## 2 Commune II 78690 80670 159360
## 3 Commune III 63792 64874 128666
## 4 Commune IV 152153 152373 304526
Ce sont quatre lignes qui répondent à nos critères.
Maintenant regardons ces mêmes critères, mais en termes d’alternatives. Les communes qui ont soit plus de 100000 habitants soit plus de femmes que d’hommes.
Avec R-base.
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
pop_100000_plus <- pop_df$total > 100000
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
femmes_sup_hommes <- pop_df$femme > pop_df$homme
# Mise en oeuvre de la sélection
pop_df[pop_100000_plus | femmes_sup_hommes, ]
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Colimbine 6144 6353 12497
## 2 Djelebou 11466 12091 23557
## 3 Guidimakan Keri Kaff 9798 10234 20032
## 4 Hawa Dembaya 3406 3445 6851
## 5 Karakoro 7436 7770 15206
## 6 Kayes Commune 65135 61184 126319
## 7 Kemene Tambo 8381 8574 16955
## 8 Koniakary 4061 4080 8141
## 9 Konsiga 2308 2620 4928
## 10 Koussane 10472 11118 21590
## # ... with 528 more rows
Avec dplyr
.
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000 |
# Critère 2: femme > homme
femme > homme
)
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Colimbine 6144 6353 12497
## 2 Djelebou 11466 12091 23557
## 3 Guidimakan Keri Kaff 9798 10234 20032
## 4 Hawa Dembaya 3406 3445 6851
## 5 Karakoro 7436 7770 15206
## 6 Kayes Commune 65135 61184 126319
## 7 Kemene Tambo 8381 8574 16955
## 8 Koniakary 4061 4080 8141
## 9 Konsiga 2308 2620 4928
## 10 Koussane 10472 11118 21590
## # ... with 528 more rows
Ici, nous avons nettement plus d’observations.
En ce qui concernent les critères alternatifs, dplyr
offre une commodité avec le signe %in%
. Imaginez qu’au lieu d’une seule commune, Bambara Maoude, que l’on souhaite sélectionner les résultats d’un groupe de commune dont on a connait le nom. Plutôt que d’utiliser |
, l’on peut passer par %in%
.
Avec R-base.
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection: valeurs logiques (TRUE/FALSE)
groupe_commune <- pop_df$admin3_nom == "Bambara Maoude" |
pop_df$admin3_nom == "Segou Commune" |
pop_df$admin3_nom == "Soumpi" |
pop_df$admin3_nom == "Ansongo"
# Mise en oeuvre de la sélection
pop_df[groupe_commune, ]
## # A tibble: 4 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Segou Commune 66819 66682 133501
## 2 Bambara Maoude 8315 8170 16485
## 3 Soumpi 8547 8401 16948
## 4 Ansongo 14707 15384 30091
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(admin3_nom %in% c("Bambara Maoude", "Segou Commune", "Soumpi", "Ansongo"))
## # A tibble: 4 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Segou Commune 66819 66682 133501
## 2 Bambara Maoude 8315 8170 16485
## 3 Soumpi 8547 8401 16948
## 4 Ansongo 14707 15384 30091
Moins de lignes! Même résultat!
6.2.6 Tri d’observations: arrange
Souvent, il arrive qu’à la suite d’opération de sélections (aussi bien de variables que de colonnes) que l’on souhaite ordonner les résultats selon un ordre bien précis.
Considérons qu’après avoir filter pour ne garder que les communes qui ont plus de 100000 habitants et plus de femmes que d’hommes, que nous souhaitions ordonner la population.
Avec R-base
# Sélection des variables d'intérêt
pop_df <- adm3_pop_2009[ , c("admin3_nom", "homme", "femme")]
# Création d'une nouvelle variable: numérique
pop_df$total <- pop_df$femme + pop_df$homme
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
pop_100000_plus <- pop_df$total > 100000
# Critère de sélection (1): valeurs logiques (TRUE/FALSE)
femmes_sup_hommes <- pop_df$femme > pop_df$homme
# Mise en oeuvre de la sélection
pop_df_filtre <- pop_df[pop_100000_plus | femmes_sup_hommes, ]
# Tri: ordre croissant
pop_decroissant <- order(pop_df_filtre$total)
# Mise en oeuvre du tri
pop_df_filtre[pop_decroissant, ]
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Adarmalane 463 492 955
## 2 Bassirou 825 893 1718
## 3 Arham 1358 1461 2819
## 4 Soignebougou 1547 1552 3099
## 5 Ouro Modi 1566 1762 3328
## 6 Sokourani Missirikoro 1632 1740 3372
## 7 Diou 1744 1760 3504
## 8 Kende 1805 1921 3726
## 9 Somo 1853 1891 3744
## 10 M'bouna 1894 1937 3831
## # ... with 528 more rows
Pour voir la liste avec l’ordre décroissant.
# Tri: ordre décroissant
pop_decroissant <- order(pop_df_filtre$total, decreasing = TRUE)
# Mise en oeuvre du tri
pop_df_filtre[pop_decroissant, ]
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Commune VI 237951 231702 469653
## 2 Commune V 206749 206517 413266
## 3 Commune I 168308 166587 334895
## 4 Commune IV 152153 152373 304526
## 5 Sikasso Commune 114171 112447 226618
## 6 Kalabancoro 81018 80864 161882
## 7 Commune II 78690 80670 159360
## 8 Koutiala Commune 70905 70539 141444
## 9 Segou Commune 66819 66682 133501
## 10 Commune III 63792 64874 128666
## # ... with 528 more rows
Avec dplyr
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000 |
# Critère 2: femme > homme
femme > homme
) %>%
arrange(total)
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Adarmalane 463 492 955
## 2 Bassirou 825 893 1718
## 3 Arham 1358 1461 2819
## 4 Soignebougou 1547 1552 3099
## 5 Ouro Modi 1566 1762 3328
## 6 Sokourani Missirikoro 1632 1740 3372
## 7 Diou 1744 1760 3504
## 8 Kende 1805 1921 3726
## 9 Somo 1853 1891 3744
## 10 M'bouna 1894 1937 3831
## # ... with 528 more rows
Avec l’ordre décroissant.
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000 |
# Critère 2: femme > homme
femme > homme
) %>%
arrange(desc(total))
## # A tibble: 538 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Commune VI 237951 231702 469653
## 2 Commune V 206749 206517 413266
## 3 Commune I 168308 166587 334895
## 4 Commune IV 152153 152373 304526
## 5 Sikasso Commune 114171 112447 226618
## 6 Kalabancoro 81018 80864 161882
## 7 Commune II 78690 80670 159360
## 8 Koutiala Commune 70905 70539 141444
## 9 Segou Commune 66819 66682 133501
## 10 Commune III 63792 64874 128666
## # ... with 528 more rows
Il est facile de constater que plus l’opération se complixifie, plus R-base requiert lignes et d’objets intermédiaires tandis que dplyr
se contente tout s’allonger la chaîne de passation, prenant un objet de départ, le transformant avec une fonction et le passant à une autre.
L’on peut agrémenter arrange
avec une fonction qui spécifie le nombre d’observations à afficher ou à sauvegarder: top_n
. Celle-ci peut opérer par le haut (les valeurs élevées)…
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000 |
# Critère 2: femme > homme
femme > homme
) %>%
# Tri: décroissant
arrange(total) %>%
# Sélection des 5 premières observations
top_n(n = 5, wt = total)
## # A tibble: 5 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Sikasso Commune 114171 112447 226618
## 2 Commune IV 152153 152373 304526
## 3 Commune I 168308 166587 334895
## 4 Commune V 206749 206517 413266
## 5 Commune VI 237951 231702 469653
…ou par le bas (les valeurs faibles).
adm3_pop_2009 %>%
# Sélection des variables d'intérêt
select(admin3_nom, homme, femme) %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Sélection d'observations d'intérêt
filter(
# Critère 1: population > 100000
total > 100000 |
# Critère 2: femme > homme
femme > homme
) %>%
# Tri: décroissant
arrange(total) %>%
# Sélection des 5 dernières observations
top_n(n = -5, wt = total)
## # A tibble: 5 x 4
## admin3_nom homme femme total
## <chr> <dbl> <dbl> <dbl>
## 1 Adarmalane 463 492 955
## 2 Bassirou 825 893 1718
## 3 Arham 1358 1461 2819
## 4 Soignebougou 1547 1552 3099
## 5 Ouro Modi 1566 1762 3328
6.2.7 Vers l’agrégation: group_by
et summarize
Jusque là, nous avons opéré en ajoutant ou enlevant des variables, en sélectionnant ou excluant des observations. Ces opérations ont toutes été intra-individuelles c’est-à-dire qu’à aucun moment il n’a été nécéssaire de mélanger les valeurs de deux ou plusieurs observations. Or, il arrive souvant que le data scientist ait besoin d’agréer des valeurs pour approfondir sa propre compréhension ou tout simplement synthétiser ses résultats. dplyr
comptent deux fonctions sont pratiques pour ce faire. Il s’agit de group_by
et summarize
(summarise
aussi marche). Elles viennent consolider les quatre que nous avons vues. La première group_by
définit les groupes sur lesquels les opérations à venir doivent être exécutées. Quant à summarize
, elle explicite ces opérations. Illustrons pour mieux comprendre.
Supposons que l’on veuille agréger la population par admin1_nom
.
adm3_pop_2009 %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Spécification du niveau d'agrégation
group_by(admin1_nom) %>%
# Opération d'agrégation
summarize(population = sum(total)) %>%
# Tri: décroissant
arrange(desc(population))
## # A tibble: 9 x 2
## admin1_nom population
## <chr> <dbl>
## 1 Sikasso 2644458
## 2 Koulikouro 2419212
## 3 Segou 2321651
## 4 Mopti 2038855
## 5 Kayes 2013076
## 6 Bamako 1810366
## 7 Tombouctou 671005
## 8 Gao 542304
## 9 Kidal 67739
Et si voulions connaitre en même temps le nombre de communes par région?
adm3_pop_2009 %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Spécification du niveau d'agrégation
group_by(admin1_nom) %>%
# Opération d'agrégation
summarize(population = sum(total),
nombre_communes = n()) %>%
# Tri: décroissant
arrange(desc(population))
## # A tibble: 9 x 3
## admin1_nom population nombre_communes
## <chr> <dbl> <int>
## 1 Sikasso 2644458 147
## 2 Koulikouro 2419212 108
## 3 Segou 2321651 118
## 4 Mopti 2038855 108
## 5 Kayes 2013076 129
## 6 Bamako 1810366 6
## 7 Tombouctou 671005 52
## 8 Gao 542304 24
## 9 Kidal 67739 11
Avec une seule ligne à l’intérieur de summarize
, l’on peut ajouter d’autres opérations. Nous pouvons même ajouter la population moyenne par commune.
adm3_pop_2009 %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Spécification du niveau d'agrégation
group_by(admin1_nom) %>%
# Opération d'agrégation
summarize(population = sum(total),
nombre_communes = n()) %>%
# Création d'une nouvelle variable %>%
mutate(pop_par_commune = population / nombre_communes) %>%
# Tri: décroissant
arrange(desc(population))
## # A tibble: 9 x 4
## admin1_nom population nombre_communes pop_par_commune
## <chr> <dbl> <int> <dbl>
## 1 Sikasso 2644458 147 17990.
## 2 Koulikouro 2419212 108 22400.
## 3 Segou 2321651 118 19675.
## 4 Mopti 2038855 108 18878.
## 5 Kayes 2013076 129 15605.
## 6 Bamako 1810366 6 301728.
## 7 Tombouctou 671005 52 12904.
## 8 Gao 542304 24 22596
## 9 Kidal 67739 11 6158.
summarize
acceptent la majorité des fonctions statistiques de R-base: sum
pour la somme, mean
pour la moyenne, sd
pour l’écart-type, min
pour le minimum, max
pour le maximum, etc.
Il est utile de noter que, bien que les deux fonctions opèrent généralement en paire, elles ne sont pas toutefois obligées d’être ensemble…enfin, pas tout le temps.
Considérons par exemple que l’on veut agréger la population totale aussi bien pour les hommes que pour les femmes. Comme le groupe de référence est l’ensemble des observations (toutes les communes), l’on n’a pas besoin de group_by
.
adm3_pop_2009 %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Opérations d'agrégation
summarize(
# Hommes
homme = sum(homme),
# Femmes
femme = sum(femme),
# Total
total = sum(total)
)
## # A tibble: 1 x 3
## homme femme total
## <dbl> <dbl> <dbl>
## 1 7204994 7323672 14528666
Là, nous avons utilisé summarize
sans group_by
. Maintenant, faisons l’inverse. Déterminons la part de chaque commune dans la population régionale. Et gardons seulement ceux qui représentent plus de 5% de la population de la région.
adm3_pop_2009 %>%
# Création d'une nouvelle variable
mutate(total = homme + femme) %>%
# Spécification du niveau d'agrégation
group_by(admin1_nom) %>%
# Création d'une nouvelle variable
mutate(
# Population au niveau de admin1_nom
population_region = sum(total),
# Ratio population de la commune / population de la région
part_commune = total / population_region
) %>%
# Filtre: part > 20%
filter(part_commune > 0.05) %>%
# Tri des résultats: ordre décroissant
arrange(desc(part_commune)) %>%
# Sélection des variables d'intérêt
select(contains("nom"), part_commune)
## # A tibble: 28 x 5
## # Groups: admin1_nom [9]
## admin0_nom admin1_nom admin2_nom admin3_nom part_commune
## <chr> <chr> <chr> <chr> <dbl>
## 1 Mali Kidal Kidal Kidal 0.383
## 2 Mali Bamako Bamako Commune VI 0.259
## 3 Mali Bamako Bamako Commune V 0.228
## 4 Mali Bamako Bamako Commune I 0.185
## 5 Mali Bamako Bamako Commune IV 0.168
## 6 Mali Gao Gao Gao 0.159
## 7 Mali Kidal Tessalit Adjelhoc 0.117
## 8 Mali Bamako Bamako Commune II 0.0880
## 9 Mali Gao Gao Sony Aliber 0.0878
## 10 Mali Sikasso Sikasso Sikasso Commune 0.0857
## # ... with 18 more rows