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 R. 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 R.

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 R.

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("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 ...

R 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("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  : Factor w/ 71 levels ".","100","101",..: 1 42 6 8 7 22 16 5 21 12 ...
##  $ 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("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 = "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 = "naissance.Rdata")

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

rm(naissance)
load("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 = "naissance_mon_df.Rdata")
rm(naissance, mon_df)
class(mon_df)
## Error in eval(expr, envir, enclos): object 'mon_df' not found
load("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, R 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 = "naissance_mon_df.Rdata")
rm(naissance_mon_df)
load("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é 10 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)
##  int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
typeof(naissance$AGE)
## [1] "integer"
# 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]])
##  int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
str(naissance[["AGE"]])
##  int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
# Dernière façon 'liste', utiliser le `[]`, car une liste est un vecteur :
str(naissance[2])
## 'data.frame':    189 obs. of  1 variable:
##  $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
typeof(naissance[2])
## [1] "list"
str(naissance["AGE"])
## 'data.frame':    189 obs. of  1 variable:
##  $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
# 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])
##  int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
str(naissance[, "AGE"])
##  int [1:189] 19 33 20 21 18 21 22 17 29 26 ...
# 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])
## 'data.frame':    189 obs. of  1 variable:
##  $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
# !!! 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))
## 'data.frame':    189 obs. of  1 variable:
##  $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
str(subset(naissance, select = "AGE"))
## 'data.frame':    189 obs. of  1 variable:
##  $ AGE: int  19 33 20 21 18 21 22 17 29 26 ...
str(subset(naissance, select = AGE))
## '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.

# naissance$c('ID', 'AGE', 'LWT', 'SMOKE') naissance[[c(1:3, 5)]]
# naissance[[c('ID', 'AGE', 'LWT', 'SMOKE')]]
naissance[c(1:3, 5)]
naissance[c("ID", "AGE", "LWT", "SMOKE")]
naissance[, c(1:3, 5)]
naissance[, c("ID", "AGE", "LWT", "SMOKE")]
subset(naissance, select = c(1:3, 5))
subset(naissance, select = c("ID", "AGE", "LWT", "SMOKE"))
subset(naissance, select = c(ID, AGE, LWT, SMOKE))

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
## [18]  40  41  45  46  50  53  54  57  65  68  71  72  73  75  78  79  86
## [35]  93  94  95  98  99 102 109 113 115 128 131 133 140 141 142 145 146
## [52] 148 153 154 156 157 158 160 161 165 166 169 171 172 173 176 177 178
## [69] 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 : 85, 20, 143, 2, "Non-Fumeur", 0, 0, 0, 0, 2500

naissance[nrow(naissance) + 1, ] <- c(85, 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 85  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("naissance.txt")
naissance$SMOKE <- factor(naissance$SMOKE, labels = c("Non-Fumeur", "Fumeur"))

naissance[nrow(naissance) + 1, ] <- data.frame(85, 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 85  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  4  28 120    3     Fumeur   1  0  1   0  709
## 2 10  29 130    1 Non-Fumeur   0  0  1   2 1021
## 3 11  34 187    2     Fumeur   0  1  0   0 1135
## 4 13  25 105    3 Non-Fumeur   1  1  0   0 1330
## 5 15  25  85    3 Non-Fumeur   0  0  1   0 1474
## 6 16  27 150    3 Non-Fumeur   0  0  0   0 1588
# 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
## 178  68  0  0   3 2414
## 26  112  0  0   0 2877
## 186  81  0  0   2 2495
## 24  109  0  0   0 2863
## 42  129  0  0   2 3062
## 71  162  0  0   0 3317
nais_fus3 <- merge(nais1, nais3)
head(nais_fus3)
##   ID AGE LWT RACE      SMOKE PTL HT UI FVT  BWT
## 1  4  28 120    3     Fumeur   1  0  1   0  709
## 2 10  29 130    1 Non-Fumeur   0  0  1   2 1021
## 3 11  34 187    2     Fumeur   0  1  0   0 1135
## 4 13  25 105    3 Non-Fumeur   1  1  0   0 1330
## 5 15  25  85    3 Non-Fumeur   0  0  1   0 1474
## 6 16  27 150    3 Non-Fumeur   0  0  0   0 1588
identical(nais_fus1, nais_fus3)
## [1] FALSE

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
180 17 120 3 Fumeur 0 0 0 0 3572
44 20 80 3 Fumeur 0 0 1 0 2211
117 17 113 2 Non-Fumeur 0 0 0 1 2920
179 23 123 3 Non-Fumeur 0 0 0 0 3544
135 19 132 3 Non-Fumeur 0 0 0 0 3090
59 23 187 2 Fumeur 0 0 0 1 2367
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)
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
85 19 182 2 Non-Fumeur 0 0 0 0 2500
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

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
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
136 16 27 150 3 Non-Fumeur 0 0 0 0 1588

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.tbl(naissance)
nais
## # A tibble: 190 x 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
## # … with 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])
## Classes 'tbl_df', 'tbl' and 'data.frame':    190 obs. of  1 variable:
##  $ AGE: num  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   85  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.