Manipulation avec dplyr#

le package dplyr#

Dans ce cours, afin de manipuler les données, nous allons utiliser la librairie dplyr qui assure une manipulation plus intuitive des données. Toutefois, vous pouvez utiliser tout autre libraire ou même les fonctions de base de R.

# install.packages("dplyr")

D’abord, téléchargeons un petit df afin d’illustrer la théorie. Dans ce df, nous avons les données d’un cycliste qui est sorti un jour d’été faire un petit tour dans l’île de Montréal. Chaque observation, représente le nombre de km parcourus d’un parcours (lap), le temps que ça a pris, la vitesse moyenne en km/h de chaque lap, la puissance moyenne en watts et finalement, les battements de cours par minutes.

df<-read.csv("https://raw.githubusercontent.com/nmeraihi/data/master/exemple_2.txt")
df
A data.frame: 5 × 5
kmtempsvitesseMoyennepuissanceMoyennebpm
<dbl><chr><dbl><int><int>
1.244:01 19.1160134
4.849:42 30.2133146
1.021:57 30.8141139
17.6136:1129.2125144
9.2719:1029.0121143

Il possible d’ordonner les données avec la fonction de base de R appelé order. Par exemple, on voudrait ordonner notre df en ordre croissant sur la variable puissanceMoyenne

df[order(df$puissanceMoyenne),]
A data.frame: 5 × 5
kmtempsvitesseMoyennepuissanceMoyennebpm
<dbl><chr><dbl><int><int>
5 9.2719:1029.0121143
417.6136:1129.2125144
2 4.849:42 30.2133146
3 1.021:57 30.8141139
1 1.244:01 19.1160134

Par défaut, l’ordre est est croissant, on peut le rendre décroissant en ajoutant l’argument decreasing = T

df[order(df$vitesseMoyenne, decreasing = T),]
A data.frame: 5 × 5
kmtempsvitesseMoyennepuissanceMoyennebpm
<dbl><chr><dbl><int><int>
3 1.021:57 30.8141139
2 4.849:42 30.2133146
417.6136:1129.2125144
5 9.2719:1029.0121143
1 1.244:01 19.1160134

Toutefois, lorsque nous avons une base de données comportant un nombre plus important de variables, la syntaxe peut devenir plus compliquée et lourde d’écriture. Regardons un autre exemple:

df_ass <-read.csv("https://raw.githubusercontent.com/nmeraihi/data/master/assurance.csv", header = T)
head(df_ass)
A data.frame: 6 × 27
numeropoldebut_polfin_polfreq_paiementlanguetype_profalimentationtype_territoireutilisationpresence_alarmecheveuxcout1cout2cout3cout4cout5cout6cout7nbsinequipe
<int><chr><chr><int><chr><chr><chr><chr><chr><int><chr><dbl><dbl><lgl><lgl><lgl><lgl><lgl><int><int>
1 411-4-199610-4-199712FTechnicienCarnivoreSemi-urbainTravail-occasionnel1Bruns NANANANANANANA03
2 411-4-199710-4-199812FTechnicienCarnivoreSemi-urbainTravail-occasionnel1BlondsNANANANANANANA03
3 411-4-200217-7-200212FTechnicienCarnivoreSemi-urbainTravail-occasionnel1Bruns NANANANANANANA03
4 418-7-200210-4-200312FTechnicienCarnivoreSemi-urbainTravail-occasionnel1BlondsNANANANANANANA03
5 411-4-200310-4-200412FTechnicienCarnivoreSemi-urbainTravail-occasionnel1Bruns NANANANANANANA03
6123-5-1995 2-5-1996 1FIngénieur CarnivoreSemi-urbainTravail-quotidien 1BlondsNANANANANANANA03

Affichons notre base de données en ordre croissant sur le nombre de sinistres et le numéro de police;

df_ass[order(df_ass$nbsin, df_ass$numeropol, decreasing = T),]
A data.frame: 1001 × 27
numeropoldebut_polfin_polfreq_paiementlanguetype_profalimentationtype_territoireutilisationpresence_alarmecheveuxcout1cout2cout3cout4cout5cout6cout7nbsinequipe
<int><chr><chr><int><chr><chr><chr><chr><chr><int><chr><dbl><dbl><lgl><lgl><lgl><lgl><lgl><int><int>
988200613-6-1996 12-6-1997 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns 3.160124e+02 40.31056NANANANANA23
90218201-10-1996 30-9-1997 1FMédecin Carnivore Semi-urbainTravail-quotidien 1Bruns 1.465031e+02 780.73913NANANANANA23
861173310-5-1998 9-5-1999 1FInfirmièreCarnivore Semi-urbainTravail-occasionnel0Bruns 7.611553e+02 173.15528NANANANANA23
67211383-10-2002 27-3-2003 12FInfirmièreCarnivore Rural Travail-occasionnel1Bruns 1.745925e+03 1000.81367NANANANANA23
470 69218-6-2001 17-6-2002 12FTechnicienCarnivore Semi-urbainTravail-occasionnel0Blonds6.760745e+02 239.21118NANANANANA23
451 66119-5-1998 18-5-1999 12FAutre Carnivore Rural Loisir 0Bruns 1.068516e+03 127.31677NANANANANA23
414 61217-3-1996 10-2-1997 12FTechnicienCarnivore Rural Travail-occasionnel0Bruns 4.152733e+0210586.13043NANANANANA23
416 6123-4-1997 10-2-1998 12FTechnicienCarnivore Rural Travail-occasionnel0Bruns 4.191863e+02 866.93168NANANANANA23
387 57929-6-1995 28-6-1996 12FAvocat Carnivore Semi-urbainTravail-occasionnel1Blonds2.647826e+02 2105.92547NANANANANA23
388 57929-6-1996 28-6-1997 12FAvocat VégétarienSemi-urbainTravail-occasionnel1Bruns 6.344658e+02 510.38509NANANANANA23
289 38714-5-1998 22-2-1999 12FTechnicienVégétarienSemi-urbainTravail-occasionnel1Bruns 6.465839e+00 331.08696NANANANANA23
263 3735-4-1998 4-4-1999 12FTechnicienVégétarienSemi-urbainTravail-occasionnel0Bruns 5.057329e+02 1776.34783NANANANANA23
235 29921-3-1998 30-11-199812FActuaire Carnivore Semi-urbainTravail-occasionnel0Bruns 2.170062e+02 57.75155NANANANANA23
132 14015-4-1995 14-4-1996 12FMédecin VégétalienSemi-urbainTravail-occasionnel1Bruns 4.666087e+02 469.65839NANANANANA23
118 1164-9-1998 11-6-1999 1FInfirmièreCarnivore Urbain Travail-occasionnel1Bruns 3.167205e+02 1803.69565NANANANANA23
66 7920-11-199721-6-1998 12FIngénieur VégétalienRural Travail-quotidien 0Bruns 1.201242e+01 927.62733NANANANANA23
52 7115-2-1996 14-2-1997 1FMédecin Carnivore Semi-urbainTravail-quotidien 0Bruns 2.227901e+03 2001.62733NANANANANA23
1001203614-3-2001 13-3-2002 12FMédecin Carnivore Semi-urbainTravail-occasionnel0Bruns 2.310518e+05 NANANANANANA13
992202230-10-199520-11-199512FInfirmièreVégétalienUrbain Travail-quotidien 1Bruns 4.865839e+01 NANANANANANA13
989200613-6-1998 12-6-1999 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Blonds9.957019e+02 NANANANANANA13
991200613-9-2000 12-6-2001 12FTechnicienVégétarienSemi-urbainTravail-occasionnel1Bruns 8.286087e+02 NANANANANANA13
96419667-7-1995 22-5-1996 12FInfirmièreCarnivore Urbain Travail-occasionnel1Bruns 7.399578e+03 NANANANANANA13
972196613-7-2000 1-4-2001 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns 1.721677e+02 NANANANANANA13
97319662-4-2001 6-7-2001 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns 4.098696e+02 NANANANANANA13
95519416-6-1997 5-6-1998 12FActuaire Carnivore Rural Travail-occasionnel0Bruns 6.278944e+02 NANANANANANA13
949192017-5-1999 16-5-2000 12FTechnicienCarnivore Urbain Travail-occasionnel0Bruns 4.354161e+02 NANANANANANA13
94019155-8-1999 4-8-2000 1FInfirmièreCarnivore Semi-urbainTravail-occasionnel1Bruns 5.925901e+02 NANANANANANA13
92018691-10-1995 4-5-1996 1FTechnicienCarnivore Semi-urbainTravail-occasionnel0Bruns 2.256770e+02 NANANANANANA13
92118695-5-1996 4-5-1997 1FTechnicienCarnivore Semi-urbainTravail-occasionnel0Bruns 7.903975e+02 NANANANANANA13
92418695-5-1999 4-5-2000 1FTechnicienCarnivore Semi-urbainTravail-occasionnel0Blonds2.036584e+02 NANANANANANA13
332313-12-199631-1-1997 12FMédecin Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
34231-2-1997 31-1-1998 12FMédecin Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
35231-2-1998 31-1-1999 12FMédecin Carnivore Semi-urbainTravail-quotidien 0BlondsNANANANANANANA03
21156-1-1998 21-8-1998 12FTechnicienCarnivore Semi-urbainTravail-occasionnel0Bruns NANANANANANANA03
221522-8-1998 5-1-1999 12FTechnicienCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
24156-1-2000 16-4-2000 12FTechnicienCarnivore Urbain Travail-occasionnel0BlondsNANANANANANANA03
251517-4-2000 5-1-2001 12FTechnicienCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
27156-1-2002 6-8-2002 12FTechnicienCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
28157-8-2002 1-12-2002 12FTechnicienCarnivore Urbain Travail-occasionnel0BlondsNANANANANANANA03
29152-12-2002 5-1-2003 12FTechnicienCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
30156-1-2003 5-1-2004 12FTechnicienCarnivore Urbain Travail-occasionnel0BlondsNANANANANANANA03
161429-10-19973-11-1997 12FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
17144-11-1997 28-10-199812FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
181429-10-199812-3-1999 12FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
191413-3-1999 28-10-199912FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
6123-5-1995 2-5-1996 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1BlondsNANANANANANANA03
7123-5-1996 2-5-1997 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
8123-5-1997 2-5-1998 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
9123-5-1998 2-5-1999 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
10123-5-1999 2-5-2000 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
11123-5-2000 2-5-2001 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
12123-5-2001 30-5-2001 1FIngénieur Carnivore Semi-urbainTravail-quotidien 1Bruns NANANANANANANA03
131231-5-2001 2-5-2002 1FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
14123-5-2002 12-12-2002 1FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
151213-12-20022-5-2003 1FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
1 411-4-1996 10-4-1997 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns NANANANANANANA03
2 411-4-1997 10-4-1998 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1BlondsNANANANANANANA03
3 411-4-2002 17-7-2002 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns NANANANANANANA03
4 418-7-2002 10-4-2003 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1BlondsNANANANANANANA03
5 411-4-2003 10-4-2004 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns NANANANANANANA03

Dans le tableau affiché ci-haut, on voit bien que cette fonction ne nous permet pas d’appliquer un ordre croissant ou décroissant sur une variable précise

arrange#

Maintenant, utilisons le paquet (package) dplyr qui nous permet de plus facilement d’appliquer un ordre quelconque sur une variable précise indépendamment des autres variables;

library(dplyr, warn.conflicts = FALSE)
arrange(df_ass, desc(nbsin), numeropol)
A data.frame: 1001 × 27
numeropoldebut_polfin_polfreq_paiementlanguetype_profalimentationtype_territoireutilisationpresence_alarmecheveuxcout1cout2cout3cout4cout5cout6cout7nbsinequipe
<int><chr><chr><int><chr><chr><chr><chr><chr><int><chr><dbl><dbl><lgl><lgl><lgl><lgl><lgl><int><int>
7115-2-1996 14-2-1997 1FMédecin Carnivore Semi-urbainTravail-quotidien 0Bruns 2227.900621 2001.62733NANANANANA23
7920-11-199721-6-1998 12FIngénieur VégétalienRural Travail-quotidien 0Bruns 12.012422 927.62733NANANANANA23
1164-9-1998 11-6-1999 1FInfirmièreCarnivore Urbain Travail-occasionnel1Bruns 316.720497 1803.69565NANANANANA23
14015-4-1995 14-4-1996 12FMédecin VégétalienSemi-urbainTravail-occasionnel1Bruns 466.608696 469.65839NANANANANA23
29921-3-1998 30-11-199812FActuaire Carnivore Semi-urbainTravail-occasionnel0Bruns 217.006211 57.75155NANANANANA23
3735-4-1998 4-4-1999 12FTechnicienVégétarienSemi-urbainTravail-occasionnel0Bruns 505.732919 1776.34783NANANANANA23
38714-5-1998 22-2-1999 12FTechnicienVégétarienSemi-urbainTravail-occasionnel1Bruns 6.465839 331.08696NANANANANA23
57929-6-1995 28-6-1996 12FAvocat Carnivore Semi-urbainTravail-occasionnel1Blonds 264.782609 2105.92547NANANANANA23
57929-6-1996 28-6-1997 12FAvocat VégétarienSemi-urbainTravail-occasionnel1Bruns 634.465839 510.38509NANANANANA23
61217-3-1996 10-2-1997 12FTechnicienCarnivore Rural Travail-occasionnel0Bruns 415.27329210586.13043NANANANANA23
6123-4-1997 10-2-1998 12FTechnicienCarnivore Rural Travail-occasionnel0Bruns 419.186335 866.93168NANANANANA23
66119-5-1998 18-5-1999 12FAutre Carnivore Rural Loisir 0Bruns 1068.515528 127.31677NANANANANA23
69218-6-2001 17-6-2002 12FTechnicienCarnivore Semi-urbainTravail-occasionnel0Blonds 676.074534 239.21118NANANANANA23
11383-10-2002 27-3-2003 12FInfirmièreCarnivore Rural Travail-occasionnel1Bruns 1745.925466 1000.81367NANANANANA23
173310-5-1998 9-5-1999 1FInfirmièreCarnivore Semi-urbainTravail-occasionnel0Bruns 761.155280 173.15528NANANANANA23
18201-10-1996 30-9-1997 1FMédecin Carnivore Semi-urbainTravail-quotidien 1Bruns 146.503106 780.73913NANANANANA23
200613-6-1996 12-6-1997 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns 316.012422 40.31056NANANANANA23
1526-6-1996 5-1-1997 12FTechnicienCarnivore Semi-urbainTravail-occasionnel0Bruns 413.428571 NANANANANANA13
156-1-1999 5-1-2000 12FTechnicienVégétarienUrbain Travail-occasionnel0Bruns 192.093168 NANANANANANA13
156-1-2001 5-1-2002 12FTechnicienCarnivore Urbain Travail-occasionnel0Blonds1590.652174 NANANANANANA13
6223-9-1998 22-9-1999 1FInfirmièreCarnivore Semi-urbainTravail-quotidien 0Bruns 1339.484472 NANANANANANA13
7124-3-1995 30-5-1995 1FMédecin Carnivore Semi-urbainTravail-quotidien 1Bruns 603.720497 NANANANANANA13
7131-5-1995 3-8-1995 1FMédecin Carnivore Semi-urbainTravail-quotidien 1Blonds4127.689441 NANANANANANA13
7115-2-1998 27-5-1998 1FMédecin VégétarienSemi-urbainTravail-quotidien 0Bruns 345.590062 NANANANANANA13
7531-7-1996 14-8-1996 12FHockeyeur VégétarienRural Travail-occasionnel0Bruns 473.279503 NANANANANANA13
8130-5-2001 31-1-2002 12FTechnicienCarnivore Rural Travail-quotidien 0Bruns 2518.968944 NANANANANANA13
8130-5-2002 29-5-2003 12FTechnicienCarnivore Rural Travail-quotidien 0Bruns 423.881988 NANANANANANA13
829-5-1997 8-5-1998 12FTechnicienCarnivore Semi-urbainTravail-occasionnel0Bruns 2955.093168 NANANANANANA13
853-1-2002 2-1-2003 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns 1064.801242 NANANANANANA13
978-12-2000 24-5-2001 12FInfirmièreCarnivore Urbain Travail-occasionnel1Bruns 1821.583851 NANANANANANA13
196623-5-1996 6-7-1996 12FInfirmièreCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-1996 6-7-1997 12FInfirmièreCarnivore Urbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-1997 6-7-1998 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-1998 6-7-1999 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-1999 10-8-1999 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
196611-8-1999 6-7-2000 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-2000 12-7-2000 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-2001 6-7-2002 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
19667-7-2002 6-7-2003 12FInfirmièreVégétarienUrbain Travail-occasionnel0Bruns NANANANANANANA03
198915-11-199514-11-199612FInfirmièreVégétalienRural Travail-occasionnel1Bruns NANANANANANANA03
198915-11-199626-6-1997 12FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
198927-6-1997 26-8-1997 12FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
198927-8-1997 14-11-199712FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
198928-11-199727-1-1998 12FInfirmièreVégétarienRural Travail-occasionnel1Bruns NANANANANANANA03
199331-12-199530-12-199612FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
199331-12-199630-12-199712FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
199331-12-199730-12-199812FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
199331-12-199822-12-199912FIngénieur Carnivore Semi-urbainTravail-quotidien 0Bruns NANANANANANANA03
200613-6-1995 31-12-199512FTechnicienCarnivore Semi-urbainTravail-occasionnel1BlondsNANANANANANANA03
20061-1-1996 22-2-1996 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1Bruns NANANANANANANA03
200623-2-1996 12-6-1996 12FTechnicienCarnivore Semi-urbainTravail-occasionnel1BlondsNANANANANANANA03
200613-6-2000 12-9-2000 12FTechnicienVégétarienSemi-urbainTravail-occasionnel1Bruns NANANANANANANA03
203525-2-1996 29-5-1996 12FHockeyeur VégétarienRural Travail-quotidien 1Bruns NANANANANANANA03
203530-5-1996 24-2-1997 12FHockeyeur VégétarienRural Travail-quotidien 1Roux NANANANANANANA03
203525-2-1997 24-2-1998 12FHockeyeur VégétarienRural Travail-quotidien 1Bruns NANANANANANANA03
203525-2-1998 24-2-1999 12FHockeyeur VégétarienRural Travail-quotidien 1Bruns NANANANANANANA03
20365-5-1998 13-3-1999 12FMédecin Carnivore Semi-urbainTravail-occasionnel0Bruns NANANANANANANA03
20367-4-1999 13-3-2000 12FMédecin Carnivore Semi-urbainTravail-occasionnel0Bruns NANANANANANANA03
203614-3-2000 26-2-2001 12FMédecin Carnivore Semi-urbainTravail-occasionnel0Bruns NANANANANANANA03
203627-2-2001 13-3-2001 12FMédecin Carnivore Semi-urbainTravail-occasionnel0Bruns NANANANANANANA03

select#

Ce paquet nous permet aussi de sélectionner des variables d’intérêt. Par exemple, dans notre df_ass, on désire seulement sélectionner les variables numeropol, type_territoire et nbsin

select(df_ass, numeropol,type_territoire, nbsin)
A data.frame: 1001 × 3
numeropoltype_territoirenbsin
<int><chr><int>
4Semi-urbain0
4Semi-urbain0
4Semi-urbain0
4Semi-urbain0
4Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
12Semi-urbain0
14Rural 0
14Rural 0
14Rural 0
14Rural 0
15Semi-urbain1
15Semi-urbain0
15Urbain 0
15Urbain 1
15Urbain 0
15Urbain 0
15Urbain 1
15Urbain 0
15Urbain 0
15Urbain 0
15Urbain 0
1966Urbain 1
1966Urbain 1
1966Urbain 0
1966Urbain 0
1989Rural 0
1989Rural 0
1989Rural 0
1989Rural 0
1989Rural 0
1993Semi-urbain0
1993Semi-urbain0
1993Semi-urbain0
1993Semi-urbain0
2006Semi-urbain0
2006Semi-urbain0
2006Semi-urbain0
2006Semi-urbain2
2006Semi-urbain1
2006Semi-urbain0
2006Semi-urbain1
2022Urbain 1
2035Rural 0
2035Rural 0
2035Rural 0
2035Rural 0
2036Semi-urbain0
2036Semi-urbain0
2036Semi-urbain0
2036Semi-urbain0
2036Semi-urbain1

filter#

Afin de filtrer des données sur des observations d’intérêt. On peut utiliser la fonction de base de R which. Par exemple dans les données Cars93 du package MASS, on voudrait extraire les véhicules ayant 8 cylindres. On voudrait également afficher que les deux variables 'Horsepower' et 'Passengers'

library(MASS, warn.conflicts = F)
Cars93[which(Cars93$Cylinders==8), c('Horsepower' , 'Passengers')]
A data.frame: 7 × 2
HorsepowerPassengers
<int><int>
102006
112955
181706
193002
381906
482785
522106

Toutefois, la fonction filter de la librairie dyplr est plus flexible lorsqu’il s’agit d’appliquer des filtres plus complexes. Essayons le même exemple avec cette fonction;

filter(Cars93, Cylinders==8)[c('Horsepower' , 'Passengers')]
A data.frame: 7 × 2
HorsepowerPassengers
<int><int>
2006
2955
1706
3002
1906
2785
2106

Si l’on cherche les médecins qui ont eu deux sinistres dans notre base de données df_ass;

filter(df_ass, nbsin==2, type_prof=="Médecin")
A data.frame: 3 × 27
numeropoldebut_polfin_polfreq_paiementlanguetype_profalimentationtype_territoireutilisationpresence_alarmecheveuxcout1cout2cout3cout4cout5cout6cout7nbsinequipe
<int><chr><chr><int><chr><chr><chr><chr><chr><int><chr><dbl><dbl><lgl><lgl><lgl><lgl><lgl><int><int>
7115-2-199614-2-1997 1FMédecinCarnivore Semi-urbainTravail-quotidien 0Bruns2227.90062001.6273NANANANANA23
14015-4-199514-4-199612FMédecinVégétalienSemi-urbainTravail-occasionnel1Bruns 466.6087 469.6584NANANANANA23
18201-10-199630-9-1997 1FMédecinCarnivore Semi-urbainTravail-quotidien 1Bruns 146.5031 780.7391NANANANANA23

mutate#

Dans ce package, on trouve aussi la fonction mutate qui permet d’ajouter de nouvelles variables à notre df

mutate(df, arrondi=round(df$vitesseMoyenne,0))
A data.frame: 5 × 6
kmtempsvitesseMoyennepuissanceMoyennebpmarrondi
<dbl><chr><dbl><int><int><dbl>
1.244:01 19.116013419
4.849:42 30.213314630
1.021:57 30.814113931
17.6136:1129.212514429
9.2719:1029.012114329

Ajoutons maintenant trois nouvlles variables;

mutate(df, arrondi=round(df$vitesseMoyenne,0), segementStrava=paste("segment",1:5,sep = "_"), arrondi_2=arrondi/2)
A data.frame: 5 × 8
kmtempsvitesseMoyennepuissanceMoyennebpmarrondisegementStravaarrondi_2
<dbl><chr><dbl><int><int><dbl><chr><dbl>
1.244:01 19.116013419segment_1 9.5
4.849:42 30.213314630segment_215.0
1.021:57 30.814113931segment_315.5
17.6136:1129.212514429segment_414.5
9.2719:1029.012114329segment_514.5

summarize#

La fonction summarize est très similaire à la fonction mutate. Toutefois, contrairement à mutate, la fonction summarize ne travaille pas sur une copie du df, mais elle crée un tout nouveau df avec les nouvelles variables.

summarise(df,TotalKmParcour=sum(km))
A data.frame: 1 × 1
TotalKmParcour
<dbl>
33.98
summarise(df,TotalKmParcour=sum(km), vitesseMoyenne= mean(df$vitesseMoyenne), puissanceMoyenne=mean(df$puissanceMoyenne))
A data.frame: 1 × 3
TotalKmParcourvitesseMoyennepuissanceMoyenne
<dbl><dbl><dbl>
33.9827.66136

On voit bien que l’écriture du code commence à être un peu plus compliquée lorsque nous avons plusieurs parenthèses dans notre fonction. Pour remédier à ce problème, nous verrons la notion de piiping;

L’opérateur Pipe: %>%#

Avant d’aller plus loin, introduisons l’opérateur de pipe:%>%. dplyr importe cet opérateur d’une autre librairie (magrittr). Cet opérateur vous permet de diriger la sortie d’une fonction vers l’entrée d’une autre fonction. Au lieu d’imbriquer des fonctions (lecture de l’intérieur vers l’extérieur), l’idée de piping est de lire les fonctions de gauche à droite.

piping data

Crédit de l’image Pipes in R Tutorial For Beginners

Lorsque nous avons écrit:

select(df_ass, numeropol, type_territoire, nbsin)
Error in select(df_ass, numeropol, type_territoire, nbsin): unused arguments (numeropol, type_territoire, nbsin)
Traceback:

Si on lit ce que nous avons écrit précédemment de l’intérieur vert l’extérieur, en utilisant le piping, nous aurons ceci:

df_ass %>%
    select (numeropol,type_territoire, nbsin)
numeropoltype_territoirenbsin
4 Semi-urbain0
4 Semi-urbain0
4 Semi-urbain0
2036 Semi-urbain0
2036 Semi-urbain1

ou;

df_ass %>%
    select (numeropol,type_territoire, nbsin) %>%
    head
numeropoltype_territoirenbsin
4 Semi-urbain0
4 Semi-urbain0
4 Semi-urbain0
4 Semi-urbain0
12 Semi-urbain0

group_by#

Nous pouvons aussi grouper les données comme nous le faisions dans SAS avec les PROC SQL

df_ass$coutTot<-rowSums(df_ass[,c(19:25)], na.rm = T, dims = 1)
df_ass
numeropoldebut_polfin_polfreq_paiementcout7nbsinequipecoutTot
4 11-4-199610-4-199712 NA 0 3 0
4 11-4-199710-4-199812 NA 0 3 0
4 11-4-200217-7-200212 NA 0 3 0
2036 27-2-200113-3-200112 NA 0 3 0.0
2036 14-3-200113-3-200212 NA 1 3 231051.8
summarise(df_ass,TotalNbSin=sum(nbsin), TotCout= sum((coutTot), na.rm = T))
TotalNbSinTotCout
156 1078791

Cherchons par exemple nombre de sinistres totaux ainsi que leurs coûts par territoire. En utilisant la syntaxe du piping, ça devient plus facile d’inclure plus de sous-groupes;

df_ass %>% 
    group_by(type_territoire) %>%
    summarise(TotalNbSin=sum(nbsin), 
              TotCout= sum((coutTot), na.rm = T)
            )
type_territoireTotalNbSinTotCout
Rural 51 547105.01
Semi-urbain80 471157.64
Urbain 25 60528.81

Jointure des bases des données#

Dans cette section, nous allons joindre deux ou plusieurs df. Mais d’abord importons deux df afin illustrer quelques exemples;

df_demo <-read.csv("https://raw.githubusercontent.com/nmeraihi/data/master/donnes_demo.csv", header = T)
df_demo
nameprovincecompanylanguedate_naissanceageeage_permisnumeropol
Shane Robinson Nova Scotia May Ltd fr 1944-10-20 72 24 1
Courtney Nguyen Saskatchewan Foley, Moore and Mitchellen 1985-12-09 31 24 5
Lori Washington Yukon Territory Robinson-Reyes fr 1970-01-27 47 28 13
Heidi Freeman Northwest Territories Singh, Esparza and Santosen 1951-06-07 65 18 84
Morgan Buchanan Northwest Territories Rollins Inc fr 1971-07-31 45 31 91
df_auto <-read.csv("https://raw.githubusercontent.com/nmeraihi/data/master/cars_info.csv", header = T)
df_auto
numeropolmarque_voiturecouleur_voiturepresence_alarmelicense_plate
1 Autres Autre 0 DW 3168
5 RENAULTAutre 0 926 1RL
13 RENAULTAutre 1 SOV 828
84 HONDA Autre 0 CBV 102
91 BMW Autre 1 UOR-0725

Dans ces deux df, nous avons une colonne en commun numeropol

df_demo$numeropol
  1. 1
  2. 5
  3. 13
  4. 16
  5. 22
  6. 28
  7. 29
  8. 49
  9. 53
  10. 57
  11. 59
  12. 65
  13. 67
  14. 68
  15. 69
  16. 72
  17. 78
  18. 83
  19. 84
  20. 91
df_auto$numeropol
  1. 1
  2. 5
  3. 13
  4. 16
  5. 22
  6. 22
  7. 28
  8. 29
  9. 49
  10. 53
  11. 53
  12. 57
  13. 59
  14. 65
  15. 65
  16. 67
  17. 68
  18. 69
  19. 69
  20. 72
  21. 78
  22. 83
  23. 84
  24. 84
  25. 91

On peut voir l’index des lignes qui se trouvent dans les deux df

match(df_demo$numeropol, df_auto$numeropol)
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 7
  7. 8
  8. 9
  9. 10
  10. 12
  11. 13
  12. 14
  13. 16
  14. 17
  15. 18
  16. 20
  17. 21
  18. 22
  19. 23
  20. 25
df_demo$numeropol[match(df_demo$numeropol, df_auto$numeropol)]
  1. 1
  2. 5
  3. 13
  4. 16
  5. 22
  6. 29
  7. 49
  8. 53
  9. 57
  10. 65
  11. 67
  12. 68
  13. 72
  14. 78
  15. 83
  16. 91
  17. <NA>
  18. <NA>
  19. <NA>
  20. <NA>

On peut aussi faire un test logique sur la présence des observations du df_demo dans df_auto;

df_demo$numeropol %in% df_auto$numeropol
  1. TRUE
  2. TRUE
  3. TRUE
  4. TRUE
  5. TRUE
  6. TRUE
  7. TRUE
  8. TRUE
  9. TRUE
  10. TRUE
  11. TRUE
  12. TRUE
  13. TRUE
  14. TRUE
  15. TRUE
  16. TRUE
  17. TRUE
  18. TRUE
  19. TRUE
  20. TRUE

ou le contraire maintenant

df_auto$numeropol %in% df_demo$numeropol 
  1. TRUE
  2. TRUE
  3. TRUE
  4. TRUE
  5. TRUE
  6. TRUE
  7. TRUE
  8. TRUE
  9. TRUE
  10. TRUE
  11. TRUE
  12. TRUE
  13. TRUE
  14. TRUE
  15. TRUE
  16. TRUE
  17. TRUE
  18. TRUE
  19. TRUE
  20. TRUE
  21. TRUE
  22. TRUE
  23. TRUE
  24. TRUE
  25. TRUE

Dans ce cas toutes les variables se trouvent dans les deux df

merge(df_demo,df_auto, by.x = "numeropol",  by.y = "numeropol") # x est le df_demo et y est le df df_auto
numeropolnameprovincecompanymarque_voiturecouleur_voiturepresence_alarmelicense_plate
1 Shane Robinson Nova Scotia May Ltd Autres Autre 0 DW 3168
5 Courtney Nguyen Saskatchewan Foley, Moore and MitchellRENAULT Autre 0 926 1RL
13 Lori Washington Yukon Territory Robinson-Reyes RENAULT Autre 1 SOV 828
84 Heidi Freeman Northwest Territories Singh, Esparza and SantosHONDA Autre 0 CBV 102
91 Morgan Buchanan Northwest Territories Rollins Inc BMW Autre 1 UOR-0725

Que serait-il arrivé si l’on n’avait pas spécifié les arguments by.x = "numeropol",  by.y = "numeropol"?

merge(df_demo,df_auto)
numeropolnameprovincecompanymarque_voiturecouleur_voiturepresence_alarmelicense_plate
1 Shane Robinson Nova Scotia May Ltd Autres Autre 0 DW 3168
5 Courtney Nguyen Saskatchewan Foley, Moore and MitchellRENAULT Autre 0 926 1RL
13 Lori Washington Yukon Territory Robinson-Reyes RENAULT Autre 1 SOV 828
84 Heidi Freeman Northwest Territories Singh, Esparza and SantosHONDA Autre 0 CBV 102
91 Morgan Buchanan Northwest Territories Rollins Inc BMW Autre 1 UOR-0725

Cela a bien fonctionné, car R a automatiquement trouvé les noms de colonnes communs au deux df;

Maintenant, changeons les noms de colonnes et voyons ce qui arrive

names(df_auto)[names(df_auto)=="numeropol"] <- "auto_numpol"

Bien évidemment, cela crée une jointure croisée comme on l’avait vu dans les cours de SAS

head(merge(df_demo,df_auto))
nameprovincecompanylanguemarque_voiturecouleur_voiturepresence_alarmelicense_plate
Shane Robinson Nova Scotia May Ltd fr Autres Autre 0 DW 3168
Courtney Nguyen Saskatchewan Foley, Moore and Mitchellen Autres Autre 0 DW 3168
Lori Washington Yukon Territory Robinson-Reyes fr Autres Autre 0 DW 3168
Jeffrey Garcia Nunavut Berger-Thompsonen Autres Autre 0 DW 3168
Colleen ColemanSaskatchewan Simmons-Smith en Autres Autre 0 DW 3168

On vient bien que dans la dernière colonne license_plate, nous obtenons la même observation ce qui est clairement une erreur;

Corrigeons le problème;

head(merge(df_demo,df_auto, by.x = "numeropol",  by.y = "auto_numpol"))
numeropolnameprovincecompanymarque_voiturecouleur_voiturepresence_alarmelicense_plate
1 Shane Robinson Nova Scotia May Ltd Autres Autre 0 DW 3168
5 Courtney Nguyen Saskatchewan Foley, Moore and MitchellRENAULT Autre 0 926 1RL
13 Lori Washington Yukon Territory Robinson-Reyes RENAULT Autre 1 SOV 828
22 Jeffrey Garcia Nunavut Berger-ThompsonVOLKSWAGEN Autre 1 453 CFM
22 Jeffrey Garcia Nunavut Berger-ThompsonVOLKSWAGEN Autre 0 FHH 537

left_join#

la fonction left_join prend toute l’information de gauche et l’information existante de la partie droite qui est basée sur le critère en commun

x<-data.frame(nom=c("Gabriel", "Adel", "NM", "Mathieu", "Amine", "Mohamed"), 
              bureaux=c("5518", "4538", "5518", "5517", "4538", "4540"))
x
nombureaux
Gabriel5518
Adel 4538
NM 5518
Amine 4538
Mohamed4540
y<-data.frame(nom=c("Gabriel", "Adel", "JP", "Mathieu", "Amine"), 
              diplome=c("M.Sc", "Ph.D", "Ph.D", "Ph.D", "Ph.D"))
y
nomdiplome
GabrielM.Sc
Adel Ph.D
JP Ph.D
MathieuPh.D
Amine Ph.D
left_join(x,y,by = "nom")
Warning message:
“Column `nom` joining factors with different levels, coercing to character vector”
nombureauxdiplome
Gabriel5518 M.Sc
Adel 4538 Ph.D
NM 5518 NA
Amine 4538 Ph.D
Mohamed4540 NA

inner_join#

Cette fonction permet de retourner seulement les éléments en commun des deux df

inner_join(x,y,by = "nom")
Warning message:
“Column `nom` joining factors with different levels, coercing to character vector”
nombureauxdiplome
Gabriel5518 M.Sc
Adel 4538 Ph.D
Mathieu5517 Ph.D
Amine 4538 Ph.D

semi_join#

Cette fonction retourne seulement les éléments du premier df qui se retrouve dans le deuxième df, sans nous retourner les éléments de ce dernier

semi_join(x,y,by = "nom")

anti_join#

Cette fonction le contraire de la précédente

anti_join(x,y,by = "nom")