Programmer en R/Manipuler un tableau de données
En R, les données tabulaires sont généralement modélisées dans des tableaux de données (data.frame
). Un tableau de données est une liste dont tous les éléments sont des vecteurs de même taille.
La librairie tibble introduit une nouvelle classe pour les tableaux de données. Les tibbles se comportent exactement comme les data.frame mais leurs options d'impression par défaut sont différentes[1].
Développée par Hadley Wickham, la librarie dplyr
a pour objectif de définir une grammaire pour la manipulation de données. Cette grammaire repose sur quelques verbes simples :
- select() permet de sélectionner les colonnes d'un jeu de données ;
- filter() permet de filtrer les lignes en fonction de conditions logiques (par exemple sélectionner les lignes où telle variable est supérieure à telle valeur, etc) ;
- rename() permet de renommer les variables ;
- summarise() permet de résumer ou synthétiser un jeu de données ;
- mutate() permet de définir de nouvelles variables ;
- arrange() permet de trier le tableau de données.
La librairie dplyr contient aussi la fonction group_by() qui permet d'effectuer chaque opération sur des sous-groupes du jeu de données.
La librairie tidyr permet de mettre en forme un jeu de données en passant notamment des données dont les valeurs sont réparties sur plusieurs colonnes dans un format long de type clé-valeur et inversement des données sous forme clé-valeur dans un format large[2]. La librarie tidyr contient donc essentiellement deux fonctions :
- la fonction gather pour passer en mode clé-valeur
- la fonction spread pour passer en mode large
Pré-requis
[modifier | modifier le wikicode]Pour cette section, il faut avoir installé dplyr
.
library(tibble)
library(tidyr)
library(dplyr)
Exemples
[modifier | modifier le wikicode]Dans cette section, nous prenons comme exemple le fichier des députés déposé par l'association Wikimédia France sur la plateforme data.gouv.fr[3]. Ce fichier est au format CSV. Pour l'importer, on utilise la fonction read_csv()
de la librairie readr
. Pour en savoir plus sur l'import des fichiers CSV, on peut consulter la page Importer un fichier CSV.
library(readr)
table_deputes <- read_csv("data/deputes.csv")
Afficher un aperçu
[modifier | modifier le wikicode]- La fonction
glimpse()
permet d'afficher un aperçu du tableau de données avec le nombre d'observations, le nombre de variables, le nom, le type et les premières valeurs de chacune des colonnes. - La fonction
str()
produit un résultat similaire - La fonction
head()
permet d'afficher les premières lignes d'un tableau de données
> table_deputes %>%
+ glimpse()
Observations: 575
Variables: 10
$ nom <chr> "François Fillon", "François de Rugy", "Hervé Gaymard", "Aurélie Filipp...
$ genre <chr> "masculin", "masculin", "masculin", "féminin", "féminin", "féminin", "m...
$ prenom <chr> "François", "François", "Hervé", "Aurélie", "Delphine", "Marion", "Jacq...
$ nom_famille <chr> "Fillon", "de Rugy", "Gaymard", "Filippetti", "Batho", "Maréchal-Le Pen...
$ date_naissance <dttm> 1954-03-04, 1973-12-06, 1960-05-31, 1973-06-17, 1973-03-23, 1989-12-10...
$ lieu_naissance <chr> "Le Mans", "Nantes", "Bourg-Saint-Maurice", "Villerupt", "Paris", "Sain...
$ circonscription <chr> "deuxième circonscription de Paris", "première circonscription de la Lo...
$ sycomore_id <int> 3009, 17282, 3322, 17302, 17264, 18477, 921, 17275, 476, 17280, 1300, 1...
$ wikidata <chr> "http://www.wikidata.org/entity/Q101410", "http://www.wikidata.org/enti...
$ frwiki <chr> "https://fr.wikipedia.org/wiki/Fran%C3%A7ois%20Fillon", "https://fr.wik...
Parcourir les données
[modifier | modifier le wikicode]Pour parcourir les données, on utilise la fonction View()
.
table_deputes %>% View()
Filtrer les lignes
[modifier | modifier le wikicode]La fonction filter()
permet de filtrer la table en fonction d'une condition logique.
Par exemple, sur la table des députés, on peut filtrer la table pour ne garder que les députés de genre féminin :
> table_deputes %>%
+ filter(genre == "féminin")
# A tibble: 150 × 10
nom genre prenom nom_famille date_naissance
<chr> <chr> <chr> <chr> <dttm>
1 Aurélie Filippetti féminin Aurélie Filippetti 1973-06-17
2 Delphine Batho féminin Delphine Batho 1973-03-23
3 Marion Maréchal-Le Pen féminin Marion Maréchal-Le Pen 1989-12-10
4 Michèle Delaunay féminin Michèle Delaunay 1947-01-08
5 Marie-George Buffet féminin Marie-George Buffet 1949-05-07
6 Valérie Boyer féminin Valérie Boyer 1962-06-11
7 Sylvia Pinel féminin Sylvia Pinel 1977-09-28
8 Marie-Arlette Carlotti féminin Marie-Arlette Carlotti 1952-01-21
9 Nathalie Kosciusko-Morizet féminin Nathalie Kosciusko-Morizet 1973-05-14
10 Cécile Duflot féminin Cécile Duflot 1975-04-01
# ... with 140 more rows, and 5 more variables: lieu_naissance <chr>, circonscription <chr>,
# sycomore_id <int>, wikidata <chr>, frwiki <chr>
On peut aussi combiner plusieurs conditions. Dans l'exemple suivant, on filtre les députés de genre féminin dont l'année de naissance est postérieure à 1976. On utilise la fonction year()
de la librairie lubridate()
pour extraire l'année de la date de naissance.
library(lubridate)
> table_deputes %>%
+ filter(genre == "féminin", year(date_naissance) >= 1976)
# A tibble: 9 × 10
nom genre prenom nom_famille date_naissance lieu_naissance
<chr> <chr> <chr> <chr> <dttm> <chr>
1 Marion Maréchal-Le Pen féminin Marion Maréchal-Le Pen 1989-12-10 Saint-Germain-en-Laye
2 Sylvia Pinel féminin Sylvia Pinel 1977-09-28 L'Union
3 Seybah Dagoma féminin Seybah Dagoma 1978-06-09 Nantes
4 Stéphanie Pernod-Beaudon féminin Stéphanie Pernod-Beaudon 1978-10-13 Bourg-en-Bresse
5 Fanélie Carrey-Conte féminin Fanélie Carrey-Conte 1980-05-16 Bègles
6 Paola Zanetti féminin Paola Zanetti 1976-09-01 Créhange
7 Virginie Duby-Muller féminin Virginie Duby-Muller 1979-08-16 Bonneville
8 Marie Le Vern féminin Marie Le Vern 1983-01-11 Bois-Guillaume
9 Marine Brenier féminin Marine Brenier 1986-08-11 Nice
# ... with 4 more variables: circonscription <chr>, sycomore_id <int>, wikidata <chr>, frwiki <chr>
La fonction slice()
permet de filtrer un tableau de données en fonction des numéros de ligne.
> table_deputes %>% slice(1:10)
# A tibble: 10 × 10
nom genre prenom nom_famille date_naissance lieu_naissance
<chr> <chr> <chr> <chr> <dttm> <chr>
1 François Fillon masculin François Fillon 1954-03-04 Le Mans
2 François de Rugy masculin François de Rugy 1973-12-06 Nantes
3 Hervé Gaymard masculin Hervé Gaymard 1960-05-31 Bourg-Saint-Maurice
4 Aurélie Filippetti féminin Aurélie Filippetti 1973-06-17 Villerupt
5 Delphine Batho féminin Delphine Batho 1973-03-23 Paris
6 Marion Maréchal-Le Pen féminin Marion Maréchal-Le Pen 1989-12-10 Saint-Germain-en-Laye
7 Jacques Bompard masculin Jacques Bompard 1943-02-24 Montpellier
8 Xavier Breton masculin Xavier Breton 1962-11-25 Darney
9 Christian Bataille masculin Christian Bataille 1946-05-13 Rieux-en-Cambrésis
10 Michèle Delaunay féminin Michèle Delaunay 1947-01-08 Clermont-Ferrand
# ... with 4 more variables: circonscription <chr>, sycomore_id <int>, wikidata <chr>, frwiki <chr>
Sélectionner des variables
[modifier | modifier le wikicode]La fonction select()
permet de sélectionner les colonnes d'un tableau de données.
Par exemple, on peut sélectionner les colonnes "nom_famille", "prenom" et "genre" :
table_deputes %>%
select(nom_famille, prenom, genre)
On peut aussi utiliser des fonctions pour sélectionner rapidement plusieurs colonnes.
- La fonction
starts_with()
sélectionne toutes les colonnes dont les noms commencent par une chaîne de caractères donnée. - La fonction
ends_with()
sélectionne toutes les colonnes dont les noms se terminent par une chaîne de caractères donnée. - La fonction
contains()
sélectionne toutes les colonnes dont les noms comprennent une chaîne de caractère donnée.
> table_deputes %>%
+ select(starts_with("nom")) %>%
+ head(n = 2)
# A tibble: 2 × 2
nom nom_famille
<chr> <chr>
1 François Fillon Fillon
2 François de Rugy de Rugy
>
> table_deputes %>%
+ select(ends_with("naissance")) %>%
+ head(n = 2)
# A tibble: 2 × 2
date_naissance lieu_naissance
<dttm> <chr>
1 1954-03-04 Le Mans
2 1973-12-06 Nantes
>
> table_deputes %>%
+ select(contains("nom")) %>%
+ head(n = 2)
# A tibble: 2 × 3
nom prenom nom_famille
<chr> <chr> <chr>
1 François Fillon François Fillon
2 François de Rugy François de Rugy
Renommer les variables
[modifier | modifier le wikicode]La fonction names()
permet d'afficher les noms de variables.
> table_deputes %>% names()
[1] "nom" "genre" "prenom" "nom_famille" "date_naissance"
[6] "lieu_naissance" "circonscription" "sycomore_id" "wikidata" "frwiki"
La fonction rename()
permet de renommer certaines variables d'un tableau de données.
Par exemple, on peut renommer la variable frwiki
en frwikipedia
.
> table_deputes %>%
+ rename(frwikipedia = frwiki) %>%
+ names()
[1] "nom" "genre" "prenom" "nom_famille" "date_naissance"
[6] "lieu_naissance" "circonscription" "sycomore_id" "wikidata" "frwikipedia"
Trier le tableau de données
[modifier | modifier le wikicode]La fonction arrange()
permet de trier le tableau de données en fonction des valeurs d'une ou plusieurs variables.
Par exemple, on peut trier le jeu de données des députés en fonction de la date de naissance des députés :
> table_deputes %>%
+ arrange(date_naissance) %>%
+ head()
# A tibble: 6 × 10
nom genre prenom nom_famille date_naissance lieu_naissance
<chr> <chr> <chr> <chr> <dttm> <chr>
1 François Scellier masculin François Scellier 1936-05-07 Amiens
2 Alfred Marie-Jeanne masculin Alfred Marie-Jeanne 1936-11-15 Rivière-Pilote
3 Lucien Degauchy masculin Lucien Degauchy 1937-06-11 Hautefontaine
4 Bernard Brochand masculin Bernard Brochand 1938-06-05 Nice
5 Jean-Claude Mathis masculin Jean-Claude Mathis 1939-08-15 Bouzonville
6 Jean-Michel Couve masculin Jean-Michel Couve 1940-01-03 Le Muy
# ... with 4 more variables: circonscription <chr>, sycomore_id <int>, wikidata <chr>, frwiki <chr>
Par défaut, la fonction arrange()
trie les valeurs par ordre ascendant. Pour trier les valeurs par ordre descendant, on peut combiner avec la fonction desc()
.
> table_deputes %>%
+ arrange(desc(date_naissance)) %>%
+ head()
# A tibble: 6 × 10
nom genre prenom nom_famille date_naissance lieu_naissance
<chr> <chr> <chr> <chr> <dttm> <chr>
1 Marion Maréchal-Le Pen féminin Marion Maréchal-Le Pen 1989-12-10 Saint-Germain-en-Laye
2 Marine Brenier féminin Marine Brenier 1986-08-11 Nice
3 Julien Dive masculin Julien Dive 1985-05-21 Saint-Quentin
4 Marie Le Vern féminin Marie Le Vern 1983-01-11 Bois-Guillaume
5 Laurent Marcangeli masculin Laurent Marcangeli 1980-12-10 Ajaccio
6 Fanélie Carrey-Conte féminin Fanélie Carrey-Conte 1980-05-16 Bègles
# ... with 4 more variables: circonscription <chr>, sycomore_id <int>, wikidata <chr>, frwiki <chr>
Définir de nouvelles variables
[modifier | modifier le wikicode]La fonction mutate()
permet de définir de nouvelles variables.
Par exemple, sur la table des députés, on a la date de naissance. On peut calculer donc calculer l'âge des députés. Pour calculer l'âge, on utilise plusieurs fonction de la librairie lubridate
. La fonction today()
donne la date d'aujourd'hui. La fonction interval()
permet de définir un intervalle de temps entre deux dates. Enfin, la fonction time_length()
permet de convertir un intervalle de temps en un nombre dans une unité donnée. Ici, on choisit d'exprimer l'âge en année. Dans l'exemple, on combine aussi avec les fonctions select()
et glimpse()
pour afficher un aperçu du nouveau jeu de données avec la nouvelle variable.
> library(lubridate)
> table_deputes %>%
+ mutate(
+ age = time_length(
+ interval(
+ start = date_naissance,
+ end = today()
+ ),
+ unit = "year"
+ )
+ ) %>%
+ select(nom, date_naissance, age) %>%
+ glimpse()
Observations: 575
Variables: 3
$ nom <chr> "François Fillon", "François de Rugy", "Hervé Gaymard", "Aurélie Filippetti", "De...
$ date_naissance <dttm> 1954-03-04, 1973-12-06, 1960-05-31, 1973-06-17, 1973-03-23, 1989-12-10, 1943-02-...
$ age <dbl> 62.74247, 42.98361, 56.50137, 43.45479, 43.69041, 26.97268, 73.76503, 54.01370, 7..
Synthétiser un tableau de données
[modifier | modifier le wikicode]La fonction summarise()
permet de synthétiser un jeu de données.
On peut par exemple reprendre l'exemple précédent et calculer l'âge moyen des députés. Pour cela, il suffit de définir la variable age = mean(age)
dans la fonction summarise()
.
> table_deputes %>%
+ mutate(
+ age = time_length(
+ interval(
+ start = date_naissance,
+ end = today()
+ ),
+ unit = "year"
+ )
+ ) %>%
+ summarise(age = mean(age))
# A tibble: 1 × 1
age
<dbl>
1 58.80746
On peut aussi calculer d'autres indicateurs comme l'écart-type, le minimum et le maximum :
> table_deputes %>%
+ mutate(
+ age = time_length(
+ interval(
+ start = date_naissance,
+ end = today()
+ ),
+ unit = "year"
+ )
+ ) %>%
+ summarise(
+ age_moyen = mean(age),
+ age_median = median(age),
+ ecarttype_age = sd(age),
+ min_age = min(age),
+ max_age = max(age)
+ )
# A tibble: 1 × 5
age_moyen age_median ecarttype_age min_age max_age
<dbl> <dbl> <dbl> <dbl> <dbl>
1 58.80746 59.48219 10.10712 26.97268 80.56712
Comprendre les opérations par sous-groupe
[modifier | modifier le wikicode]La librairie dplyr permet de définir des opérations sur des sous-groupes.
La fonction group_by() permet de définir les sous-groupes et la fonction ungroup() de revenir à un tableau de données non groupé.
La fonction group_by() peut être combiné avec mutate() et summarise().
Voir aussi
[modifier | modifier le wikicode]- anglais : Introduction to dplyr par Hadley Wickham]
- anglais : Data transformation dans l'ouvrage R for Data Science de Garrett Grolemund et Hadley Wickham
- Listes et tableaux de données sur le site Introduction à l'analyse d'enquêtes avec R et RStudio
- anglais : Tibbles dans l'ouvrage R for Data Science de Garrett Grolemund et Hadley Wickham