SAVOR: Part III

dplyr and %>%

Author

Robin Genuer & Boris Hejblum

Published

June 6, 2024

Objectifs

Ce document donne tout d’abord quelques considérations sur l’importation de données et sur les strucutres de bases de R, avant de donner quelques éléments introductifs sur l’utilisation du package dplyr.

Introduction à dplyr

Il existe un très grand nombre de packages additionnels dans . Certains apportent de nouvelles fonctionnalités (méthodes statistiques qui n’étaient pas disponible auparavant), et d’autres apportent des améliorations à des fonctionnalités déjà présentes dans .

Le package dplyr rentre essentiellement dans la 2ème catégorie. Il propose de re-définir la manipulation de données dans R, avec une syntaxe plus simple, tout en améliorant les performances lorsqu’on gère des grands tableaux de données.

Installer le package dplyr puis le charger :

# install.packages('dplyr')
library(dplyr)

Gestion de fichiers de données

Avant de se lancer dans l’utilisation de dplyr, nous allons revoir quelques principes dans la gestion des fichiers de données sous .

Importation

Le plus simple pour importer des données est d’utiliser l’outil graphique de Rstudio “Import Dataset”, présent dans l’onglet “Environnement” ou dans le menu “File”.

Sinon, on peut bien entendu utiliser la fonction read.table() et ses dérivées (read.csv(), read.delim()…).

Importer le fichier naissance.txt, puis regarder la structure du tableau créé via la fonction str().

naissance <- read.delim("../Data/naissance.txt")
str(naissance)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : int  182 155 105 108 107 124 118 103 123 113 ...
 $ RACE : int  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...

considère toutes les variables comme des suite de nombres entiers (car effectivement il n’y a pas de nombres à virgule), ce qui est correcte pour les variables quantitatives (comme l’âge ou encore le poids de l’enfant BWT). Par contre, certaines variables sont qualitatives (comme SMOKE), donc si on veut des facteurs, il faut le forcer.

Transformer la variable SMOKE en facteur, et renommer les niveaux en “Non-Fumeur” (0 dans le fichier txt) et “Fumeur” (1 dans le fichier txt).

naissance$SMOKE <- factor(naissance$SMOKE, labels = c("Non-Fumeur", "Fumeur"))
str(naissance)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : int  182 155 105 108 107 124 118 103 123 113 ...
 $ RACE : int  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 1 1 2 2 2 1 1 1 2 2 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...

Exercice 0 :

  1. Charger le fichier de données nommé naissance_na.txt.
naissance_na <- read.table("../Data/naissance_na.txt", sep = ";")
  1. Consulter la structure de l’objet créé (par exemple nommé naissance_na). Que remarquez-vous pour la variable LWT ?
str(naissance_na)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : chr  "." "155" "105" "108" ...
 $ RACE : int  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...
  1. Pour régler le problème, modifier le contenu de la case “NA.strings” lors du chargement du fichier de données avec “Import Dataset” (ou modifier le paramètre na.strings de la fonction read.table() ou de ses dérivées). Puis vérifier la nouvelle structure de l’objet.
naissance_na <- read.table("../Data/naissance_na.txt", sep = ";", na.strings = ".")
str(naissance_na)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : int  NA 155 105 108 107 124 118 103 123 113 ...
 $ RACE : int  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...
  1. A l’aide de la fonction transform(), transformer en facteur les variables RACE (1=blanche, 2=noire, 3=autres), HT (0=non, 1=oui) et UI (0=non, 1=oui) en une seule commande.
naissance_na <- transform(naissance_na,
    RACE = factor(RACE, labels=c("blanche", "noire", "autres")),
    HT = factor(HT, labels=c("non", "oui")),
    UI = factor(UI, labels=c("non", "oui")))
str(naissance_na)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : int  NA 155 105 108 107 124 118 103 123 113 ...
 $ RACE : Factor w/ 3 levels "blanche","noire",..: 2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : Factor w/ 2 levels "non","oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ UI   : Factor w/ 2 levels "non","oui": 2 1 1 2 2 1 1 1 1 1 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...
  1. Toujours à l’aide de la fonction transform(), créer deux nouvelles variables (utiliser deux commandes différentes, puis essayer en une seule fois) :

    • POIDS, contenant le poids de la mère en g (1 livre = 453 g).

    • RAPPORT, contenant le rapport entre le poids de l’enfant et celui de la mère (en grammes tous les deux).

naissance_na <- transform(naissance_na, POIDS = LWT * 453, RAPPORT = BWT/POIDS)
Error in eval(substitute(list(...)), `_data`, parent.frame()): object 'POIDS' not found
naissance_na <- transform(naissance_na, POIDS = LWT * 453)
naissance_na <- transform(naissance_na, RAPPORT = BWT/POIDS)
str(naissance_na)
'data.frame':   189 obs. of  12 variables:
 $ ID     : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE    : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT    : int  NA 155 105 108 107 124 118 103 123 113 ...
 $ RACE   : Factor w/ 3 levels "blanche","noire",..: 2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE  : int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT     : Factor w/ 2 levels "non","oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ UI     : Factor w/ 2 levels "non","oui": 2 1 1 2 2 1 1 1 1 1 ...
 $ FVT    : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT    : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...
 $ POIDS  : num  NA 70215 47565 48924 48471 ...
 $ RAPPORT: num  NA 0.0363 0.0538 0.053 0.0536 ...
  1. Utiliser la fonction dplyr::mutate() (du package dplyr) pour répondre à la question précédente en une seule commande.
naissance_na <- dplyr::mutate(naissance_na, POIDS2 = LWT * 453, RAPPORT2 = BWT/POIDS2)
str(naissance_na)
'data.frame':   189 obs. of  14 variables:
 $ ID      : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE     : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT     : int  NA 155 105 108 107 124 118 103 123 113 ...
 $ RACE    : Factor w/ 3 levels "blanche","noire",..: 2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE   : int  0 0 1 1 1 0 0 0 1 1 ...
 $ PTL     : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT      : Factor w/ 2 levels "non","oui": 1 1 1 1 1 1 1 1 1 1 ...
 $ UI      : Factor w/ 2 levels "non","oui": 2 1 1 2 2 1 1 1 1 1 ...
 $ FVT     : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT     : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...
 $ POIDS   : num  NA 70215 47565 48924 48471 ...
 $ RAPPORT : num  NA 0.0363 0.0538 0.053 0.0536 ...
 $ POIDS2  : num  NA 70215 47565 48924 48471 ...
 $ RAPPORT2: num  NA 0.0363 0.0538 0.053 0.0536 ...

Exportation

Pour écrire une table de données, on utilise la fonction write.table() ou ses dérivées.

mon_df <- data.frame(Partie = c("Intro", "Bases", "Manip"), Temps = c(0.5, 1.5, 1.5))
mon_df
  Partie Temps
1  Intro   0.5
2  Bases   1.5
3  Manip   1.5
write.csv(mon_df, file = "../Results/mon_df.csv")

Sauvegarde

On peut aussi sauvegarder une table au format Rdata (qui est un format propre à R). Pour cela on utilise save() :

save(naissance, file = "../Results/naissance.Rdata")

L’avantage est que lorsqu’on recharge le fichier avec la fonction load(), il garde la bonne structure :

rm(naissance)
load("../Results/naissance.Rdata")
str(naissance)
'data.frame':   189 obs. of  10 variables:
 $ ID   : int  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : int  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : int  182 155 105 108 107 124 118 103 123 113 ...
 $ RACE : int  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 1 1 2 2 2 1 1 1 2 2 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : int  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : int  2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ...

On remarque qu’on a pas besoin d’affecter le résultat de load() à un objet. Ceci est dû au fait, qu’on peut sauvegarder plusieurs objets de la session dans un même fichier .Rdata. Et on pourra tous les recharger ensuite :

save(naissance, mon_df, file = "../Results/naissance_mon_df.Rdata")
rm(naissance, mon_df)
class(mon_df)
Error in eval(expr, envir, enclos): object 'mon_df' not found
load("../Results/naissance_mon_df.Rdata")
class(mon_df)
[1] "data.frame"

Ce comportement est pratique, mais peut parfois s’avérer trompeur. Si on a beaucoup d’objets dans notre environnement, et qu’on charge un objet .Rdata avec plusieurs objets (dont on ne se souvient pas, ou dont on ne connaît pas le nom), il est difficile de s’y retrouver. De plus, lors du chargement, peut écraser des objets déjà présents avec le même nom.

Conseil : mettre tout ce qu’on veut sauver dans une liste, et sauver cette liste sous format .Rdata en gardant le même nom :

naissance_mon_df <- list(naissance = naissance, mon_df = mon_df)
save(naissance_mon_df, file = "../Results/naissance_mon_df.Rdata")
rm(naissance_mon_df)
load("../Results/naissance_mon_df.Rdata")

Opérations sur les tableaux de données

Sélection, suppression, ajout

Exercice 1 : Sélection de colonnes

  1. J’ai dénombré 11 façons de sélectionner la variable AGE. En gardant en tête qu’un data.frame est une liste de colonnes, essayer d’en trouver un maximum.
# Pour sélectionner une colonne, on peut utiliser l'aspect 'liste' du
# `data.frame`, avec le `$`
str(naissance$AGE)
typeof(naissance$AGE)
# le `$` extrait la composante de la liste `naissance` nommée `AGE`

# Toujours côté 'liste', on peut également utiliser le `[[]]`, qui exécute la
# même opération, et qui peut s'utiliser avec le numéro de la variable à la
# place du nom :
str(naissance[[2]])
str(naissance[["AGE"]])

# Dernière façon 'liste', utiliser le `[]`, car une liste est un vecteur :
str(naissance[2])
typeof(naissance[2])
str(naissance["AGE"])

# Nous voyons, que contrairement à avant où nous avions extrait un vecteur,
# nous avons ici extrait un sous-dataframe (ou encore une sous-liste). Ce
# dernier point est important à garder en tête, car il peut être source de
# nombreux bugs...

# On peut aussi utiliser le côté 'matrice' du dataframe, avec le `[,]` :
str(naissance[, 2])
str(naissance[, "AGE"])
# Ici nous avons extrait la colonne numéro 2 de la 'matrice'. Par contre, **ce
# n'est plus un dataframe !**

# Si on souhaite garder la structure de dataframe, il faut rajouter l'option
# `drop = FALSE` :
str(naissance[, 2, drop = FALSE])
#!!! ATTENTION : Ce comportement est connu comme étant une source d'erreurs fréquente dans `R` quand on programme ses propres fonctions !!!**

# Sinon, on peut utiliser la fonction `subset()` :
str(subset(naissance, select = 2))
str(subset(naissance, select = "AGE"))
str(subset(naissance, select = AGE))
 int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
[1] "integer"
 int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
 int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
[1] "list"
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
 int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
 int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
  1. Utiliser la fonction select du package dplyr pour sélectionner la variable AGE et regarder comment elle se comporte.
str(dplyr::select(naissance, 2))
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
str(dplyr::select(naissance, AGE))
'data.frame':   189 obs. of  1 variable:
 $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...

Exercice 2 : Sélection de plusieurs colonnes

Essayer tous les commandes précédentes pour extraire, en même temps, les 4 colonnes ID, AGE, LWT et SMOKE.

head(naissance$c("ID", "AGE", "LWT", "SMOKE"))
Error in head(naissance$c("ID", "AGE", "LWT", "SMOKE")): attempt to apply non-function
head(naissance[[c(1:3, 5)]])
Error in .subset2(x, i, exact = exact): recursive indexing failed at level 2
head(naissance[[c("ID", "AGE", "LWT", "SMOKE")]])
Error in .subset2(x, i, exact = exact): recursive indexing failed at level 2
head(naissance[c(1:3, 5)])
head(naissance[c("ID", "AGE", "LWT", "SMOKE")])
head(naissance[, c(1:3, 5)])
head(naissance[, c("ID", "AGE", "LWT", "SMOKE")])
head(subset(naissance, select = c(1:3, 5)))
head(subset(naissance, select = c("ID", "AGE", "LWT", "SMOKE")))
head(subset(naissance, select = c(ID, AGE, LWT, SMOKE)))

head(dplyr::select(naissance, ID, AGE, LWT, SMOKE))

Exercice 3 : Sélection de lignes

Sélectionner les 5 premières lignes, puis les 5 dernières lignes (en 2 commandes) en utilisant une commande de base puis la fonction dplyr::slice(). Afficher le résultat dans une jolie table grâce à la fonction kable()du package knitr.

# En ce qui concerne les lignes, nous sommes obligés de considérer l'aspect
# 'matrice' du dataframe :
premiers <- naissance[1:5, ]
n <- nrow(naissance)
derniers <- naissance[(n - 5):n, ]

# Avec la fonction `dplyr::slice()` :
prems <- dplyr::slice(naissance, 1:5)
derns <- dplyr::slice(naissance, (n - 5):n)
knitr::kable(dplyr::slice(naissance, c(1:5, nrow(naissance) - 4:0)))
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
85 19 182 2 Non-Fumeur 0 0 1 0 2523
86 33 155 3 Non-Fumeur 0 0 0 3 2551
87 20 105 1 Fumeur 0 0 0 1 2557
88 21 108 1 Fumeur 0 0 1 2 2594
89 18 107 1 Fumeur 0 0 1 0 2600
79 28 95 1 Fumeur 0 0 0 2 2466
81 14 100 3 Non-Fumeur 0 0 0 2 2495
82 23 94 3 Fumeur 0 0 0 0 2495
83 17 142 2 Non-Fumeur 0 1 0 0 2495
84 21 130 1 Fumeur 0 1 0 3 2495

Exercice 4 : Filtre

  1. Construire un sous-dataframe ne contenant que les individus fumeurs, en utilisant [,], puis subset(), et enfin dplyr::filter().
fum <- naissance[naissance$SMOKE == "Fumeur", ]
str(fum)
'data.frame':   74 obs. of  10 variables:
 $ ID   : int  87 88 89 94 95 100 101 103 105 113 ...
 $ AGE  : int  20 21 18 29 26 18 18 25 28 17 ...
 $ LWT  : int  105 108 107 123 113 100 100 118 120 122 ...
 $ RACE : int  1 1 1 1 1 1 1 1 1 1 ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 2 2 2 2 2 2 2 2 2 2 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  0 1 1 0 0 0 0 0 0 0 ...
 $ FVT  : int  1 2 0 1 0 0 0 3 1 0 ...
 $ BWT  : int  2557 2594 2600 2663 2665 2769 2769 2782 2821 2906 ...
summary(fum$SMOKE)
Non-Fumeur     Fumeur 
         0         74 
# La table `fum` ne contient que les individus fumeurs. On peut aussi utiliser
# la fonction `which()`, qui renvoie les indices des individus qui vérifient la
# condition :
ind_fum <- which(naissance$SMOKE == "Fumeur")
ind_fum
 [1]   3   4   5   9  10  15  16  18  20  27  29  32  33  36  37  38  39  40  41
[20]  45  46  50  53  54  57  65  68  71  72  73  75  78  79  86  93  94  95  98
[39]  99 102 109 113 115 128 131 133 140 141 142 145 146 148 153 154 156 157 158
[58] 160 161 165 166 169 171 172 173 176 177 178 179 183 184 185 187 189
fum2 <- naissance[ind_fum, ]
str(fum2)
'data.frame':   74 obs. of  10 variables:
 $ ID   : int  87 88 89 94 95 100 101 103 105 113 ...
 $ AGE  : int  20 21 18 29 26 18 18 25 28 17 ...
 $ LWT  : int  105 108 107 123 113 100 100 118 120 122 ...
 $ RACE : int  1 1 1 1 1 1 1 1 1 1 ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 2 2 2 2 2 2 2 2 2 2 ...
 $ PTL  : int  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : int  0 1 1 0 0 0 0 0 0 0 ...
 $ FVT  : int  1 2 0 1 0 0 0 3 1 0 ...
 $ BWT  : int  2557 2594 2600 2663 2665 2769 2769 2782 2821 2906 ...
# Avec `subset()`
fum_sub <- subset(naissance, SMOKE == "Fumeur")

# Avec `dplyr::filter()` :
fum_fil <- dplyr::filter(naissance, SMOKE == "Fumeur")

# Les deux syntaxes ici sont identiques. La différence est que dans dplyr il y
# a deux fonctions (`select()` et `filter()`) avec une syntaxe très simple.
  1. Donner les identifiants (colonne ID) des individus des individus présentant de l’hypertension (variable HT valant 1).
dplyr::select(dplyr::filter(naissance, HT == 1), "ID")
    ID
1   98
2  138
3  187
4  197
5  202
6   11
7   13
8   19
9   20
10  75
11  83
12  84
# avec le pipe :
naissance %>%
    filter(HT == 1) %>%
    select("ID")
    ID
1   98
2  138
3  187
4  197
5  202
6   11
7   13
8   19
9   20
10  75
11  83
12  84
  1. Sélectionner le sous-dataframe ne contenant que les individus fumeurs et âgés de moins de 20 ans.
dplyr::filter(naissance, SMOKE == "Fumeur", AGE < 20)
    ID AGE LWT RACE  SMOKE PTL HT UI FVT  BWT
1   89  18 107    1 Fumeur   0  0  1   0 2600
2  100  18 100    1 Fumeur   0  0  0   0 2769
3  101  18 100    1 Fumeur   0  0  0   0 2769
4  113  17 122    1 Fumeur   0  0  0   0 2906
5  124  19 138    1 Fumeur   0  0  0   2 2977
6  132  18  90    1 Fumeur   0  0  1   0 3076
7  133  18  90    1 Fumeur   0  0  1   0 3076
8  167  16 135    1 Fumeur   0  0  0   0 3374
9  180  17 120    3 Fumeur   0  0  0   0 3572
10 187  19 235    1 Fumeur   0  1  0   0 3629
11 189  16 135    1 Fumeur   0  0  0   0 3643
12 192  19 147    1 Fumeur   0  0  0   0 3651
13 193  19 147    1 Fumeur   0  0  0   0 3651
14 197  19 184    1 Fumeur   0  1  0   0 3756
15 205  18 120    1 Fumeur   0  0  0   2 3856
16 224  19 120    1 Fumeur   0  0  0   0 4238
17  23  19  91    1 Fumeur   2  0  1   0 1885
18  34  19 112    1 Fumeur   0  0  1   0 2084
19  37  17 130    3 Fumeur   1  0  1   0 2125
20  45  17 110    1 Fumeur   0  0  0   0 2225
21  50  18 110    2 Fumeur   1  0  0   0 2296
22  68  17 120    1 Fumeur   0  0  0   3 2414
23  78  14 101    3 Fumeur   1  0  0   0 2466
  1. Donner les indices des individus ayant un poids inférieur à 110 (le poids de la mère est en livres) ou ayant un bébé de poids inférieur à 2,5 kg.
naissance %>%
    filter(LWT < 110 | BWT < 2500) %>%
    select("ID", "LWT", "BWT")
    ID LWT  BWT
1   87 105 2557
2   88 108 2594
3   89 107 2600
4   93 103 2637
5   96  95 2722
6   98  95 2750
7   99 107 2750
8  100 100 2769
9  101 100 2769
10 102  98 2778
11 107 100 2835
12 118  90 2948
13 127 109 3033
14 132  90 3076
15 133  90 3076
16 137  85 3090
17 141  95 3147
18 146 103 3203
19 181 105 3572
20 188  95 3637
21 216  95 3997
22   4 120  709
23  10 130 1021
24  11 187 1135
25  13 105 1330
26  15  85 1474
27  16 150 1588
28  17  97 1588
29  18 128 1701
30  19 132 1729
31  20 165 1790
32  22 105 1818
33  23  91 1885
34  24 115 1893
35  25 130 1899
36  26  92 1928
37  27 150 1928
38  28 200 1928
39  29 155 1936
40  30 103 1970
41  31 125 2055
42  32  89 2055
43  33 102 2082
44  34 112 2084
45  35 117 2084
46  36 138 2100
47  37 130 2125
48  40 120 2126
49  42 130 2187
50  43 130 2187
51  44  80 2211
52  45 110 2225
53  46 105 2240
54  47 109 2240
55  49 148 2282
56  50 110 2296
57  51 121 2296
58  52 100 2301
59  54  96 2325
60  56 102 2353
61  57 110 2353
62  59 187 2367
63  60 122 2381
64  61 105 2381
65  62 115 2381
66  63 120 2395
67  65 142 2410
68  67 130 2410
69  68 120 2414
70  69 110 2424
71  71 120 2438
72  75 154 2442
73  76 105 2450
74  77 190 2466
75  78 101 2466
76  79  95 2466
77  81 100 2495
78  82  94 2495
79  83 142 2495
80  84 130 2495

Exercice 5 : Suppression de lignes ou de colonnes

En essayant avec [,], subset() et les fonctions de dplyr :

  1. Supprimer la première ligne du jeu de données.

  2. Supprimer les colonnes “AGE”, “LWT”, “RACE”, “BWT”.

Indice : utiliser la même syntaxe que pour la sélection mais avec le signe - pour indiquer les éléments à supprimer…

# Pour supprimer des lignes ou des colonnes, on peut utiliser `[,]` :
naissance_sans_ind1 <- naissance[-1, ]
nrow(naissance_sans_ind1)
[1] 188
naissance_suppr_cro <- naissance[, -c(2:4, 10)]
head(naissance_suppr_cro)
  ID      SMOKE PTL HT UI FVT
1 85 Non-Fumeur   0  0  1   0
2 86 Non-Fumeur   0  0  0   3
3 87     Fumeur   0  0  0   1
4 88     Fumeur   0  0  1   2
5 89     Fumeur   0  0  1   0
6 91 Non-Fumeur   0  0  0   0
# naissance_sans_AGE <- naissance[, -c('AGE', 'LWT', 'RACE', 'BWT')] Cette
# dernière opération n'est pas possible.

# Là encore, les fonctions `subset()` et `select()` permettent plus
# d'opérations avec une syntaxe très simple :
naissance_suprr_sub <- subset(naissance, select = -c(AGE:RACE, BWT))
naissance_suprr_sel <- dplyr::select(naissance, -c(AGE:RACE, BWT))

Exercice 6 : Ajout de lignes ou de colonnes

Ajouter un une ligne (un individu) possédant les valeurs suivantes : 1, 20, 143, 2, "Non-Fumeur", 0, 0, 0, 0, 2500

naissance[nrow(naissance) + 1, ] <- c(1, 20, 143, 2, "Non-Fumeur", 0, 0, 0, 0, 2500)
tail(naissance)
    ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
185 79  28  95    1     Fumeur   0  0  0   2 2466
186 81  14 100    3 Non-Fumeur   0  0  0   2 2495
187 82  23  94    3     Fumeur   0  0  0   0 2495
188 83  17 142    2 Non-Fumeur   0  1  0   0 2495
189 84  21 130    1     Fumeur   0  1  0   3 2495
190  1  20 143    2 Non-Fumeur   0  0  0   0 2500
# Apparemment tout va bien...
str(naissance)
'data.frame':   190 obs. of  10 variables:
 $ ID   : chr  "85" "86" "87" "88" ...
 $ AGE  : chr  "19" "33" "20" "21" ...
 $ LWT  : chr  "182" "155" "105" "108" ...
 $ RACE : chr  "2" "3" "1" "1" ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 1 1 2 2 2 1 1 1 2 2 ...
 $ PTL  : chr  "0" "0" "0" "0" ...
 $ HT   : chr  "0" "0" "0" "0" ...
 $ UI   : chr  "1" "0" "0" "1" ...
 $ FVT  : chr  "0" "3" "1" "2" ...
 $ BWT  : chr  "2523" "2551" "2557" "2594" ...
# Mais on vient en fait de casser notre jeu de données...

naissance <- read.delim("../Data/naissance.txt")
naissance$SMOKE <- factor(naissance$SMOKE, labels = c("Non-Fumeur", "Fumeur"))

naissance[nrow(naissance) + 1, ] <- data.frame(1, 20, 143, 2, "Non-Fumeur", 0, 0,
    0, 0, 2500)
tail(naissance)
    ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
185 79  28  95    1     Fumeur   0  0  0   2 2466
186 81  14 100    3 Non-Fumeur   0  0  0   2 2495
187 82  23  94    3     Fumeur   0  0  0   0 2495
188 83  17 142    2 Non-Fumeur   0  1  0   0 2495
189 84  21 130    1     Fumeur   0  1  0   3 2495
190  1  20 143    2 Non-Fumeur   0  0  0   0 2500
str(naissance)
'data.frame':   190 obs. of  10 variables:
 $ ID   : num  85 86 87 88 89 91 92 93 94 95 ...
 $ AGE  : num  19 33 20 21 18 21 22 17 29 26 ...
 $ LWT  : num  182 155 105 108 107 124 118 103 123 113 ...
 $ RACE : num  2 3 1 1 1 3 1 3 1 1 ...
 $ SMOKE: Factor w/ 2 levels "Non-Fumeur","Fumeur": 1 1 2 2 2 1 1 1 2 2 ...
 $ PTL  : num  0 0 0 0 0 0 0 0 0 0 ...
 $ HT   : num  0 0 0 0 0 0 0 0 0 0 ...
 $ UI   : num  1 0 0 1 1 0 0 0 0 0 ...
 $ FVT  : num  0 3 1 2 0 0 1 1 1 0 ...
 $ BWT  : num  2523 2551 2557 2594 2600 ...

NB: On peut rajouter une colonne (une variable), à l’aide de $, transform() ou mutate() (comme vu précédemment).

Fusion

La fonction merge() permet de fusionner deux tableaux de données :

head(naissance)
  ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
1 85  19 182    2 Non-Fumeur   0  0  1   0 2523
2 86  33 155    3 Non-Fumeur   0  0  0   3 2551
3 87  20 105    1     Fumeur   0  0  0   1 2557
4 88  21 108    1     Fumeur   0  0  1   2 2594
5 89  18 107    1     Fumeur   0  0  1   0 2600
6 91  21 124    3 Non-Fumeur   0  0  0   0 2622
nais1 <- naissance[, 1:6]
head(nais1)
  ID AGE LWT RACE      SMOKE PTL
1 85  19 182    2 Non-Fumeur   0
2 86  33 155    3 Non-Fumeur   0
3 87  20 105    1     Fumeur   0
4 88  21 108    1     Fumeur   0
5 89  18 107    1     Fumeur   0
6 91  21 124    3 Non-Fumeur   0
nais2 <- naissance[, c(1, 7:10)]
head(nais2)
  ID HT UI FVT  BWT
1 85  0  1   0 2523
2 86  0  0   3 2551
3 87  0  0   1 2557
4 88  0  1   2 2594
5 89  0  1   0 2600
6 91  0  0   0 2622
nais_fus1 <- merge(nais1, nais2)
head(nais_fus1)
  ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
1  1  20 143    2 Non-Fumeur   0  0  0   0 2500
2  4  28 120    3     Fumeur   1  0  1   0  709
3 10  29 130    1 Non-Fumeur   0  0  1   2 1021
4 11  34 187    2     Fumeur   0  1  0   0 1135
5 13  25 105    3 Non-Fumeur   1  1  0   0 1330
6 15  25  85    3 Non-Fumeur   0  0  1   0 1474
# Ici, vu que les individus sont dans le même ordre on aurait pu utiliser la
# fonction cbind(), et la colonne ID n'est pas utile :
nais_fus2 <- cbind(nais1, nais2[, -1])
head(nais_fus2)
  ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
1 85  19 182    2 Non-Fumeur   0  0  1   0 2523
2 86  33 155    3 Non-Fumeur   0  0  0   3 2551
3 87  20 105    1     Fumeur   0  0  0   1 2557
4 88  21 108    1     Fumeur   0  0  1   2 2594
5 89  18 107    1     Fumeur   0  0  1   0 2600
6 91  21 124    3 Non-Fumeur   0  0  0   0 2622
identical(nais_fus1, nais_fus2)
[1] FALSE
# Les deux dataframes ne sont pas identitiques, car merge a classé par ordre
# croissant suivant la variable de regroupement ID, mais les informations sont
# les mêmes.

On peut également fusionner deux tableaux de données où les individus (qui doivent être les mêmes) ne sont pas dans le même ordre :

desordre <- sample(1:nrow(naissance), nrow(naissance))
nais3 <- naissance[desordre, c(1, 7:10)]
head(nais3)
     ID HT UI FVT  BWT
172  60  0  0   0 2381
152  33  0  0   2 2082
94  188  0  1   0 3637
73  164  0  0   1 3331
60  147  0  0   0 3225
24  109  0  0   0 2863
nais_fus3 <- merge(nais1, nais3)
head(nais_fus3)
  ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
1  1  20 143    2 Non-Fumeur   0  0  0   0 2500
2  4  28 120    3     Fumeur   1  0  1   0  709
3 10  29 130    1 Non-Fumeur   0  0  1   2 1021
4 11  34 187    2     Fumeur   0  1  0   0 1135
5 13  25 105    3 Non-Fumeur   1  1  0   0 1330
6 15  25  85    3 Non-Fumeur   0  0  1   0 1474
identical(nais_fus1, nais_fus3)
[1] TRUE

Exercice 7 : join

  1. Consulter l’aide de dplyr::sample_n et trouver un moyens simple de permuter les lignes du jeu de données.
naissance_perm <- sample_n(naissance, size = nrow(naissance))
knitr::kable(head(naissance_perm))
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
24 25 115 3 Non-Fumeur 0 0 0 0 1893
128 21 185 2 Fumeur 0 0 0 2 3042
164 23 115 3 Fumeur 0 0 0 1 3331
108 36 202 1 Non-Fumeur 0 0 0 1 2836
170 32 134 1 Fumeur 1 0 0 4 3430
146 20 103 3 Non-Fumeur 0 0 0 0 3203
knitr::kable(head(naissance))
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
85 19 182 2 Non-Fumeur 0 0 1 0 2523
86 33 155 3 Non-Fumeur 0 0 0 3 2551
87 20 105 1 Fumeur 0 0 0 1 2557
88 21 108 1 Fumeur 0 0 1 2 2594
89 18 107 1 Fumeur 0 0 1 0 2600
91 21 124 3 Non-Fumeur 0 0 0 0 2622
  1. Consulter l’aide de dplyr::join() (pour plus d’informations sur les fusions avec dplyr consulter cette page), puis utiliser la fonction dplyr::left_join() pour fusionner les tables nais1 et nais3.
nais_joined <- dplyr::left_join(nais1, nais3, by = "ID")
knitr::kable(head(nais_joined))
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
85 19 182 2 Non-Fumeur 0 0 1 0 2523
86 33 155 3 Non-Fumeur 0 0 0 3 2551
87 20 105 1 Fumeur 0 0 0 1 2557
88 21 108 1 Fumeur 0 0 1 2 2594
89 18 107 1 Fumeur 0 0 1 0 2600
91 21 124 3 Non-Fumeur 0 0 0 0 2622

Trier un tableau de données le long d’une colonne

Pour trier le tableau suivant la variable ID par ordre croissant, on utilise la fonction order() :

nais_orderID <- naissance[order(naissance$ID), ]
knitr::kable(head(nais_orderID))
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
190 1 20 143 2 Non-Fumeur 0 0 0 0 2500
131 4 28 120 3 Fumeur 1 0 1 0 709
132 10 29 130 1 Non-Fumeur 0 0 1 2 1021
133 11 34 187 2 Fumeur 0 1 0 0 1135
134 13 25 105 3 Non-Fumeur 1 1 0 0 1330
135 15 25 85 3 Non-Fumeur 0 0 1 0 1474

Maintenant, si on veut trier le tableau suivant l’âge par ordre décroissant :

nais_decAGE <- naissance[order(naissance$AGE, decreasing = TRUE), ]
knitr::kable(nais_decAGE[1:10, ])
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
130 226 45 123 1 Non-Fumeur 0 0 0 1 4990
23 108 36 202 1 Non-Fumeur 0 0 0 1 2836
89 183 36 175 1 Non-Fumeur 0 0 0 0 3600
33 119 35 121 2 Fumeur 1 0 0 1 2948
127 223 35 170 1 Non-Fumeur 1 0 0 1 4174
133 11 34 187 2 Fumeur 0 1 0 0 1135
2 86 33 155 3 Non-Fumeur 0 0 0 3 2551
40 127 33 109 1 Fumeur 0 0 0 1 3033
114 210 33 117 1 Non-Fumeur 0 0 1 1 3912
21 106 32 121 3 Non-Fumeur 0 0 0 2 2835

On remarque qu’il y a des ex-aequo. On peut rajouter une variable sur laquelle trier les ex-aequo, en deuxième argument de order() :

nais_decAGE_decLWT <- naissance[order(naissance$AGE, naissance$LWT, decreasing = TRUE),
    ]
knitr::kable(nais_decAGE_decLWT[1:10, ])
ID AGE LWT RACE SMOKE PTL HT UI FVT BWT
130 226 45 123 1 Non-Fumeur 0 0 0 1 4990
23 108 36 202 1 Non-Fumeur 0 0 0 1 2836
89 183 36 175 1 Non-Fumeur 0 0 0 0 3600
127 223 35 170 1 Non-Fumeur 1 0 0 1 4174
33 119 35 121 2 Fumeur 1 0 0 1 2948
133 11 34 187 2 Fumeur 0 1 0 0 1135
2 86 33 155 3 Non-Fumeur 0 0 0 3 2551
114 210 33 117 1 Non-Fumeur 0 0 1 1 3912
40 127 33 109 1 Fumeur 0 0 0 1 3033
111 207 32 186 1 Non-Fumeur 0 0 0 2 3860

Enfin, si on veut que le classement soit fait de façon croissante sur LWT, on peut procéder de la façon suivante :

nais_decAGE_LWT <- naissance[order(naissance$AGE, -naissance$LWT, decreasing = TRUE),
    ]
nais_decAGE_LWT[1:10, ]
     ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
130 226  45 123    1 Non-Fumeur   0  0  0   1 4990
89  183  36 175    1 Non-Fumeur   0  0  0   0 3600
23  108  36 202    1 Non-Fumeur   0  0  0   1 2836
33  119  35 121    2     Fumeur   1  0  0   1 2948
127 223  35 170    1 Non-Fumeur   1  0  0   1 4174
133  11  34 187    2     Fumeur   0  1  0   0 1135
40  127  33 109    1     Fumeur   0  0  0   1 3033
114 210  33 117    1 Non-Fumeur   0  0  1   1 3912
2    86  33 155    3 Non-Fumeur   0  0  0   3 2551
141  22  32 105    1     Fumeur   0  0  0   0 1818

Exercice 8 : dplyr::arrange()

  1. Utiliser la fonction dplyr::arrange() pour reproduire les tris précédents.

  2. Trier le dataframe suivant la variable SMOKE (qui est un facteur). Comment R choisit-il pour déterminer quelle modalité du facteur va apparaître en premier ?

  3. Rajouter une variable, nommée lettre au dataframe, contenant des lettres majuscules choisies alétoirement. On peut utiliser sample(letters, nrow(naissance), replace = TRUE) pour générer ce tirage aléatoire.

  4. Trier le dataframe suivant la nouvelle variable lettre.

La classe tlb

Le package s’appuie sur une nouvelle classe d’objets : tbl. Le résultat affiché lorsqu’on tape le nom du tableau est tronqué pour cette nouvelle classe :

nais <- as_tibble(naissance)
nais
# A tibble: 190 × 10
      ID   AGE   LWT  RACE SMOKE        PTL    HT    UI   FVT   BWT
   <dbl> <dbl> <dbl> <dbl> <fct>      <dbl> <dbl> <dbl> <dbl> <dbl>
 1    85    19   182     2 Non-Fumeur     0     0     1     0  2523
 2    86    33   155     3 Non-Fumeur     0     0     0     3  2551
 3    87    20   105     1 Fumeur         0     0     0     1  2557
 4    88    21   108     1 Fumeur         0     0     1     2  2594
 5    89    18   107     1 Fumeur         0     0     1     0  2600
 6    91    21   124     3 Non-Fumeur     0     0     0     0  2622
 7    92    22   118     1 Non-Fumeur     0     0     0     1  2637
 8    93    17   103     3 Non-Fumeur     0     0     0     1  2637
 9    94    29   123     1 Fumeur         0     0     0     1  2663
10    95    26   113     1 Fumeur         0     0     0     0  2665
# ℹ 180 more rows
class(nais)
[1] "tbl_df"     "tbl"        "data.frame"

De plus, le comportement de la sélection de colonne est changé : on garde la structure de tableau de données même lorsqu’on sélectionne une seule colonne :

str(naissance[, 2])
 num [1:190] 19 33 20 21 18 21 22 17 29 26 ...
str(nais[, 2])
tibble [190 × 1] (S3: tbl_df/tbl/data.frame)
 $ AGE: num [1:190] 19 33 20 21 18 21 22 17 29 26 ...

Exercice 9 : dplyr::arrange()

  1. Utiliser la fonctiondplyr::arrange() pour ordonner le tableau de données naissance par age, avec les poids de naissance par ordre décroissant pour les égalités.
arrange(naissance, AGE, desc(BWT))
     ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
1   213  14 135    1 Non-Fumeur   0  0  0   0 3941
2    81  14 100    3 Non-Fumeur   0  0  0   2 2495
3    78  14 101    3     Fumeur   1  0  0   0 2466
4   102  15  98    2 Non-Fumeur   0  0  0   0 2778
5    62  15 115    3 Non-Fumeur   0  0  1   0 2381
6    57  15 110    1 Non-Fumeur   0  0  0   0 2353
7   216  16  95    3 Non-Fumeur   0  0  0   1 3997
8   206  16 170    2 Non-Fumeur   0  0  0   4 3860
9   189  16 135    1     Fumeur   0  0  0   0 3643
10  166  16 112    2 Non-Fumeur   0  0  0   0 3374
11  167  16 135    1     Fumeur   0  0  0   0 3374
12  143  16 110    3 Non-Fumeur   0  0  0   0 3175
13   25  16 130    3 Non-Fumeur   0  0  0   1 1899
14  180  17 120    3     Fumeur   0  0  0   0 3572
15  147  17 119    3 Non-Fumeur   0  0  0   0 3225
16  148  17 119    3 Non-Fumeur   0  0  0   0 3225
17  116  17 113    2 Non-Fumeur   0  0  0   1 2920
18  117  17 113    2 Non-Fumeur   0  0  0   1 2920
19  113  17 122    1     Fumeur   0  0  0   0 2906
20   93  17 103    3 Non-Fumeur   0  0  0   1 2637
21   83  17 142    2 Non-Fumeur   0  1  0   0 2495
22   71  17 120    2 Non-Fumeur   0  0  0   2 2438
23   68  17 120    1     Fumeur   0  0  0   3 2414
24   45  17 110    1     Fumeur   0  0  0   0 2225
25   37  17 130    3     Fumeur   1  0  1   0 2125
26  208  18 120    3 Non-Fumeur   0  0  0   1 3884
27  205  18 120    1     Fumeur   0  0  0   2 3856
28  168  18 229    2 Non-Fumeur   0  0  0   0 3402
29  132  18  90    1     Fumeur   0  0  1   0 3076
30  133  18  90    1     Fumeur   0  0  1   0 3076
31  100  18 100    1     Fumeur   0  0  0   0 2769
32  101  18 100    1     Fumeur   0  0  0   0 2769
33   89  18 107    1     Fumeur   0  0  1   0 2600
34   50  18 110    2     Fumeur   1  0  0   0 2296
35   49  18 148    3 Non-Fumeur   0  0  0   0 2282
36  224  19 120    1     Fumeur   0  0  0   0 4238
37  197  19 184    1     Fumeur   0  1  0   0 3756
38  192  19 147    1     Fumeur   0  0  0   0 3651
39  193  19 147    1     Fumeur   0  0  0   0 3651
40  187  19 235    1     Fumeur   0  1  0   0 3629
41  181  19 105    3 Non-Fumeur   0  0  0   0 3572
42  142  19 115    3 Non-Fumeur   0  0  0   0 3175
43  135  19 132    3 Non-Fumeur   0  0  0   0 3090
44  129  19 189    1 Non-Fumeur   0  0  0   2 3062
45  124  19 138    1     Fumeur   0  0  0   2 2977
46   97  19 150    3 Non-Fumeur   0  0  0   1 2733
47   96  19  95    3 Non-Fumeur   0  0  0   0 2722
48   85  19 182    2 Non-Fumeur   0  0  1   0 2523
49   34  19 112    1     Fumeur   0  0  1   0 2084
50   33  19 102    1 Non-Fumeur   0  0  0   2 2082
51   23  19  91    1     Fumeur   2  0  1   0 1885
52  217  20 158    1 Non-Fumeur   0  0  0   1 3997
53  211  20 170    1     Fumeur   0  0  0   0 3940
54  201  20 120    3 Non-Fumeur   0  0  0   0 3770
55  177  20 127    3 Non-Fumeur   0  0  0   0 3487
56  172  20 121    2     Fumeur   0  0  0   0 3444
57  160  20 141    1 Non-Fumeur   2  0  1   1 3317
58  155  20 169    3 Non-Fumeur   1  0  1   1 3274
59  146  20 103    3 Non-Fumeur   0  0  0   0 3203
60  104  20 120    3 Non-Fumeur   0  0  1   0 2807
61   87  20 105    1     Fumeur   0  0  0   1 2557
62    1  20 143    2 Non-Fumeur   0  0  0   0 2500
63   76  20 105    3 Non-Fumeur   0  0  0   3 2450
64   60  20 122    2     Fumeur   0  0  0   0 2381
65   51  20 121    1     Fumeur   1  0  1   0 2296
66   47  20 109    3 Non-Fumeur   0  0  0   0 2240
67   44  20  80    3     Fumeur   0  0  1   0 2211
68   40  20 120    2     Fumeur   0  0  0   3 2126
69   31  20 125    3 Non-Fumeur   0  0  1   0 2055
70   27  20 150    1     Fumeur   0  0  0   2 1928
71  219  21 115    1 Non-Fumeur   0  0  0   1 4054
72  186  21 134    3 Non-Fumeur   0  0  0   2 3629
73  144  21 110    3     Fumeur   0  0  1   0 3203
74  131  21 160    1 Non-Fumeur   0  0  0   0 3062
75  128  21 185    2     Fumeur   0  0  0   2 3042
76   91  21 124    3 Non-Fumeur   0  0  0   0 2622
77   88  21 108    1     Fumeur   0  0  1   2 2594
78   84  21 130    1     Fumeur   0  1  0   3 2495
79   52  21 100    3 Non-Fumeur   1  0  0   4 2301
80   30  21 103    3 Non-Fumeur   0  0  0   0 1970
81   28  21 200    2 Non-Fumeur   0  0  1   2 1928
82   20  21 165    1     Fumeur   0  1  0   1 1790
83  220  22 129    1 Non-Fumeur   0  0  0   0 4111
84  204  22 169    1 Non-Fumeur   0  0  0   0 3827
85  184  22 125    1 Non-Fumeur   0  0  0   1 3614
86  174  22 131    1 Non-Fumeur   0  0  0   1 3460
87  161  22 158    2 Non-Fumeur   1  0  0   2 3317
88  162  22 112    1     Fumeur   2  0  0   0 3317
89  140  22 130    1     Fumeur   0  0  0   0 3132
90  138  22 120    1 Non-Fumeur   0  1  0   1 3100
91  137  22  85    3     Fumeur   0  0  0   0 3090
92   98  22  95    3 Non-Fumeur   0  1  0   0 2750
93   92  22 118    1 Non-Fumeur   0  0  0   1 2637
94   67  22 130    1     Fumeur   0  0  0   1 2410
95   42  22 130    1     Fumeur   1  0  1   1 2187
96  200  23 110    1 Non-Fumeur   0  0  0   1 3770
97  182  23 130    1 Non-Fumeur   0  0  0   0 3586
98  179  23 123    3 Non-Fumeur   0  0  0   0 3544
99  173  23 190    1 Non-Fumeur   0  0  0   0 3459
100 164  23 115    3     Fumeur   0  0  0   1 3331
101 149  23 119    3 Non-Fumeur   0  0  0   2 3232
102 139  23 128    3 Non-Fumeur   0  0  0   0 3104
103 130  23 130    2 Non-Fumeur   0  0  0   1 3062
104  82  23  94    3     Fumeur   0  0  0   0 2495
105  69  23 110    1     Fumeur   1  0  0   0 2424
106  63  23 120    3 Non-Fumeur   0  0  0   0 2395
107  59  23 187    2     Fumeur   0  0  0   1 2367
108  17  23  97    3 Non-Fumeur   0  0  1   1 1588
109 225  24 116    1 Non-Fumeur   0  0  0   1 4593
110 199  24 110    3 Non-Fumeur   1  0  0   0 3770
111 196  24 110    1 Non-Fumeur   0  0  0   1 3728
112 185  24 133    1 Non-Fumeur   0  0  0   0 3614
113 156  24 115    3 Non-Fumeur   0  0  0   2 3274
114 150  24 110    3 Non-Fumeur   0  0  0   0 3232
115 136  24 115    1 Non-Fumeur   0  0  0   2 3090
116 118  24  90    1     Fumeur   1  0  0   1 2948
117  61  24 105    2     Fumeur   0  0  0   0 2381
118  36  24 138    1 Non-Fumeur   0  0  0   0 2100
119  29  24 155    1     Fumeur   1  0  0   0 1936
120  19  24 132    3 Non-Fumeur   0  1  0   0 1729
121  18  24 128    2 Non-Fumeur   1  0  0   1 1701
122 221  25 130    1 Non-Fumeur   0  0  0   2 4153
123 215  25 120    1 Non-Fumeur   0  0  0   2 3983
124 202  25 241    2 Non-Fumeur   0  1  0   0 3790
125 188  25  95    1     Fumeur   3  0  1   0 3637
126 169  25 140    1 Non-Fumeur   0  0  0   1 3416
127 120  25 155    1 Non-Fumeur   0  0  0   1 2977
128 121  25 125    2 Non-Fumeur   0  0  0   0 2977
129 111  25 120    3 Non-Fumeur   0  0  1   2 2877
130 103  25 118    1     Fumeur   0  0  0   3 2782
131  46  25 105    3 Non-Fumeur   1  0  0   1 2240
132  32  25  89    3 Non-Fumeur   2  0  0   1 2055
133  26  25  92    1     Fumeur   0  0  0   0 1928
134  24  25 115    3 Non-Fumeur   0  0  0   0 1893
135  15  25  85    3 Non-Fumeur   0  0  1   0 1474
136  13  25 105    3 Non-Fumeur   1  1  0   0 1330
137 218  26 160    3 Non-Fumeur   0  0  0   0 4054
138 154  26 133    3     Fumeur   2  0  0   0 3260
139 115  26 168    2     Fumeur   0  0  0   0 2920
140  95  26 113    1     Fumeur   0  0  0   0 2665
141  77  26 190    1     Fumeur   0  0  0   0 2466
142  75  26 154    3 Non-Fumeur   1  1  0   1 2442
143  54  26  96    3 Non-Fumeur   0  0  0   0 2325
144  35  26 117    1     Fumeur   1  0  0   0 2084
145 125  27 124    1     Fumeur   0  0  0   0 2992
146  43  27 130    2 Non-Fumeur   0  0  1   0 2187
147  16  27 150    3 Non-Fumeur   0  0  0   0 1588
148 214  28 130    3 Non-Fumeur   0  0  0   0 3969
149 212  28 134    3 Non-Fumeur   0  0  0   1 3941
150 159  28 250    3     Fumeur   0  0  0   6 3303
151 151  28 140    1 Non-Fumeur   0  0  0   0 3234
152 112  28 167    1 Non-Fumeur   0  0  0   0 2877
153 109  28 120    3 Non-Fumeur   0  0  0   0 2863
154 105  28 120    1     Fumeur   0  0  0   1 2821
155  79  28  95    1     Fumeur   0  0  0   2 2466
156   4  28 120    3     Fumeur   1  0  1   0  709
157 209  29 130    1     Fumeur   0  0  0   2 3884
158 190  29 135    1 Non-Fumeur   0  0  0   1 3651
159 191  29 154    1 Non-Fumeur   0  0  0   1 3651
160 123  29 140    1     Fumeur   0  0  0   2 2977
161 114  29 150    1 Non-Fumeur   0  0  0   2 2920
162  94  29 123    1     Fumeur   0  0  0   1 2663
163  10  29 130    1 Non-Fumeur   0  0  1   2 1021
164 203  30 112    1 Non-Fumeur   0  0  0   1 3799
165 195  30 137    1 Non-Fumeur   0  0  0   1 3699
166 176  30 110    3 Non-Fumeur   0  0  0   0 3475
167 145  30 153    3 Non-Fumeur   0  0  0   0 3203
168 141  30  95    1     Fumeur   0  0  0   2 3147
169  99  30 107    3 Non-Fumeur   1  0  1   2 2750
170  65  30 142    1     Fumeur   1  0  0   0 2410
171 222  31 120    1 Non-Fumeur   0  0  0   2 4167
172 163  31 150    3     Fumeur   0  0  0   2 3321
173 126  31 215    1     Fumeur   0  0  0   2 3005
174 107  31 100    1 Non-Fumeur   0  0  1   3 2835
175  56  31 102    1     Fumeur   1  0  0   1 2353
176 207  32 186    1 Non-Fumeur   0  0  0   2 3860
177 175  32 170    1 Non-Fumeur   0  0  0   0 3473
178 170  32 134    1     Fumeur   1  0  0   4 3430
179 134  32 132    1 Non-Fumeur   0  0  0   4 3080
180 106  32 121    3 Non-Fumeur   0  0  0   2 2835
181  22  32 105    1     Fumeur   0  0  0   0 1818
182 210  33 117    1 Non-Fumeur   0  0  1   1 3912
183 127  33 109    1     Fumeur   0  0  0   1 3033
184  86  33 155    3 Non-Fumeur   0  0  0   3 2551
185  11  34 187    2     Fumeur   0  1  0   0 1135
186 223  35 170    1 Non-Fumeur   1  0  0   1 4174
187 119  35 121    2     Fumeur   1  0  0   1 2948
188 183  36 175    1 Non-Fumeur   0  0  0   0 3600
189 108  36 202    1 Non-Fumeur   0  0  0   1 2836
190 226  45 123    1 Non-Fumeur   0  0  0   1 4990

Introduction au pipe %>%

Exercice 10

  1. À l’aide des fonctions dplyr::group_by(), dplyr::summarize(), dplyr::n(), dplyr::filter() et dplyr::arrange(), construire le tableau de données donnant le poids moyen à la naissance par âge stratifié sur le statut tabagique, ainsi que le nombre d’observations correpondantes, et ordonné le résultat par ordre de poids moyen croissant en ne sélectionnant que les catéories pour lesquelles le poids moyen est inférieur à 2,5kg.
naissance_exo10 <- group_by(naissance, AGE, SMOKE)
naissance_exo10 <- summarise(naissance_exo10, poids_moy = mean(BWT, na.rm = TRUE),
    n = n())
naissance_exo10 <- filter(naissance_exo10, poids_moy < 2500)
naissance_exo10 <- arrange(naissance_exo10, poids_moy)
knitr::kable(naissance_exo10)
AGE SMOKE poids_moy n
34 Fumeur 1135.000 1
27 Non-Fumeur 1887.500 2
28 Fumeur 2324.750 4
24 Fumeur 2421.667 3
14 Fumeur 2466.000 1
  1. Réécrire le code de la réponse précédente à l’aide de l’opérateur %>%
naissance_exo10_pipe <- naissance %>%
    group_by(AGE, SMOKE) %>%
    summarise(poids_moy = mean(BWT, na.rm = TRUE), n = n()) %>%
    filter(poids_moy < 2500) %>%
    arrange(poids_moy)
knitr::kable(naissance_exo10_pipe)
AGE SMOKE poids_moy n
34 Fumeur 1135.000 1
27 Non-Fumeur 1887.500 2
28 Fumeur 2324.750 4
24 Fumeur 2421.667 3
14 Fumeur 2466.000 1

Résumé

Le package dplyr propose un ensemble de fonctions très simples à utiliser et permettant de réaliser toutes les opérations classiques sur les tableaux de données, avec une syntaxe très claire et compréhensible.

Pour aller plus loin, ou voir d’autres exemples, consulter cette page. On renverra également vers cet aide-mémoire.

En dehors du changement de syntaxe, les gains en temps de calcul sont souvent significatifs avec dplyr. Il existe un autre package populaire pour faire des manipulations sur les (grands) jeux de données : data.table. La syntaxe est un peu moins intuitive que dplyr, mais l’efficacité est encore accrue.