Fusionner deux tableaux des données par leurs colonnes : les jointures
Lorsqu’on analyse des données, il peut arriver qu’on ait besoin de fusionner les lignes de plusieurs tableaux de données (data frames), pour constituer un seul grand tableau de données.
Ce sont ces fonctions que nous allons explorer dans cet article.
Premier exemple : une seule variable de jointure
Les data
Considérons un premier jeu de données, nommé “fish” qui contient les quantités de poissons (en tonnes) péchés pour une année donnée, par la Belgique, le Danemark, la Croatie, l’Estonie, la Grèce, et la Finlande.
print(fish)
## geo Capture
## 1 Belgique 26860.00
## 2 Danemark 670212.83
## 3 Croatie 72865.34
## 4 Estonie 72421.83
## 5 Grèce NA
## 6 Finlande 164833.42
Considérons également, un second jeu de données, nommé “bio” qui, lui, contient les superficies de cultures agricoles biologiques déclarées par la Belgique, le Danemark et de la Croatie, mais aussi (alors que ce n’est pas le cas du jeu de données “fish”) de la Norvège, du Portugal et de la Turquie.
print(bio)
## geo SurfaceBio
## 1 Belgique 56055
## 2 Danemark 161251
## 3 Croatie 29172
## 4 Norvège 44681
## 5 Portugal 171743
## 6 Turquie 388547
Juxtaposition des colonnes
Une première façon de vouloir joindre ces deux jeux de données peut simplement consister à les “coller” l’un à côté de l’autre. Pour cela, on peut utiliser la fonction bind_cols().
library(tidyverse)
data1 <- bind_cols(fish, bio)
print(data1)
## geo Capture geo1 SurfaceBio
## 1 Belgique 26860.00 Belgique 56055
## 2 Danemark 670212.83 Danemark 161251
## 3 Croatie 72865.34 Croatie 29172
## 4 Estonie 72421.83 Norvège 44681
## 5 Grèce NA Portugal 171743
## 6 Finlande 164833.42 Turquie 388547
On peut voir ici que les 2 colonnes du data frame “fish” ont été juxtaposées aux 2 colonnes du data frame “bio”, et que la deuxième variable “geo” a été renommée “geo1”.
En regardant le data frame obtenu, on peut voir que si les données Capture et SurfaceBio des trois premières lignes concernent les mêmes pays, cela n’est plus le cas pour les trois lignes suivantes, puisque les données de pêche concernent l’Estonie, la Grèce et la Finlande et que les données de surfaces agricoles biologiques concernent la Norvège, le Portugal et la Turquie.
Ce n’est pas forcément ce que l’on souhaite !
Les jointures
Jointures à gauche
La jointure à gauche est réalisée avec la fonction left_join(). Cette fonction prend en argument les deux data frames à fusionner, ainsi que la variable de jointure (ou appariement).
left_join(df1, df2, by"var_jointure")
Dans la jointure à gauche, le premier data frame cité dans la fonction (celui qui est donc à gauche), est le data frame de référence. Ce sont les colonnes du second data frame (celui qui est à droite dans la fonction) qui vont être ajoutées au data frame de référence. Mais seules les valeurs des lignes correspondant aux modalités de la variable de jointure présentes dans le data frame de référence seront ajoutées. C’est un peu complexe à formuler alors qu’en pratique, c’est plutôt simple. Voici un exemple pour mieux comprendre. On réalise une fusion à gauche entre les data frame ‘fish” et “bio”, en considérant le pays (variable “géo”), comme variable de jointure :
data2 <-left_join(fish, bio, by="geo")
print(data2)
## geo Capture SurfaceBio
## 1 Belgique 26860.00 56055
## 2 Danemark 670212.83 161251
## 3 Croatie 72865.34 29172
## 4 Estonie 72421.83 NA
## 5 Grèce NA NA
## 6 Finlande 164833.42 NA
Le jeu de données “bio” ne contenant pas de valeur pour l’Estonie, la Grèce et la Finlande, des NA ont été ajoutées.
Remarque : si aucune variable de jointure n’est fournie à la fonction, l’appariement va être réalisé sur le plus grand nombre de variables commune (dans cet exemple, uniquement “geo”) .
data2_bis <-left_join(fish, bio)
print(data2_bis)
## geo Capture SurfaceBio
## 1 Belgique 26860.00 56055
## 2 Danemark 670212.83 161251
## 3 Croatie 72865.34 29172
## 4 Estonie 72421.83 NA
## 5 Grèce NA NA
## 6 Finlande 164833.42 NA
Jointure à droite
La jointure à droite est réalisée avec la fonction right_join(). Son principe est identique, sauf qu’ici le data.frame de référence est celui entré en deuxième position (ici bio).
data3 <- right_join(fish, bio)
print (data3)
## geo Capture SurfaceBio
## 1 Belgique 26860.00 56055
## 2 Danemark 670212.83 161251
## 3 Croatie 72865.34 29172
## 4 Norvège NA 44681
## 5 Portugal NA 171743
## 6 Turquie NA 388547
Cette fois, ce sont les données de Surface biol
Cette fois, ce sont les données de Surface biologiques qui sont complètes et les données de pêche de la Norvège, du Portugal et de la Turquie, qui ont été remplacées par des NA, car elles sont absentes du data frame “fish”.
Jointure restreinte
Une autre façon de fusionner les deux jeux de données, peut consister à ne considérer que les modalités communes de la variable de jointure (“geo”) présentes dans les deux data frames (ici la Belgique, le Danemark et la Croatie). Ce type de fusion est réalisé avec la fonction inner_join()
data4 <- inner_join(fish, bio, by="geo")
print(data4)
## geo Capture SurfaceBio
## 1 Belgique 26860.00 56055
## 2 Danemark 670212.83 161251
## 3 Croatie 72865.34 29172
Jointure complète
Une dernière façon de fusionner les deux jeux de données, peut consister à considérer l’ensemble des modalités de la variable de jointure (“geo”), celles qui sont communes aux deux jeux de données (ici la Belgique, le Danemark et la Croatie) et celles qui sont uniquement présentes dans l’un des deux jeux de données. Ce type de fusion est réalisé avec la fonction full_join() :
data5<- full_join(fish,bio)
print(data5)
## geo Capture SurfaceBio
## 1 Belgique 26860.00 56055
## 2 Danemark 670212.83 161251
## 3 Croatie 72865.34 29172
## 4 Estonie 72421.83 NA
## 5 Grèce NA NA
## 6 Finlande 164833.42 NA
## 7 Norvège NA 44681
## 8 Portugal NA 171743
## 9 Turquie NA 388547
Dans ce type de fusion, les deux data frames sont considérés sur le même plan, toutes les modalités de la variable d’ajustement, des deux data frames, sont considérées.
Second exemple : plusieurs variables de jointures
Les data
Considérons, à présent, le même fichier “fish”, mais avec en plus une variable “Year”, fixée à 2016 pour toutes les lignes. Ce jeu de donnée est renommé “fish_16”.
print(fish_16)
## geo Capture Year
## 1 Belgique 26860.00 2016
## 2 Danemark 670212.83 2016
## 3 Croatie 72865.34 2016
## 4 Estonie 72421.83 2016
## 5 Grèce NA 2016
## 6 Finlande 164833.42 2016
Considérons aussi un nouveau jeu de données, concernant les surfaces agricoles biologiques. Ce nouveau jeu de données, nommé “bio_16_17” contient les superficies de cultures agricoles biologiques de la Belgique, du Danemark et de la Croatie pour l’année 2016, et celles de l’Estonie, de la Grèce et du Portugal, pour l’année 2017:
print(bio_16_17)
## geo SurfaceBio Year
## 1 Belgique 56055 2016
## 2 Danemark 161251 2016
## 3 Croatie 29172 2016
## 4 Estonie 160837 2017
## 5 Grèce 280733 2017
## 6 Portugal 216180 2017
Examinons, comment se déroulent la juxtaposition et les jointures lorsque deux variables de jointure sont présentes :
Juxtaposition des colonnes
bind_cols(fish_16, bio_16_17)
## geo Capture Year geo1 SurfaceBio Year1
## 1 Belgique 26860.00 2016 Belgique 56055 2016
## 2 Danemark 670212.83 2016 Danemark 161251 2016
## 3 Croatie 72865.34 2016 Croatie 29172 2016
## 4 Estonie 72421.83 2016 Estonie 160837 2017
## 5 Grèce NA 2016 Grèce 280733 2017
## 6 Finlande 164833.42 2016 Portugal 216180 2017
Dans le cas de la juxtaposition, rien de nouveau, si ce n’est que cette fois, ce sont les 3 colonnes du data frame bio_16_17 qui ont été “collées” aux 3 colonnes du data frame bio_16_17.
Les jointures
Jointure à gauche
Comme mentionné précédemment, lorsque aucune variable de jointure n’est passée en argument, les fonctions x_join() utilisent, par défaut le maximum de variables de jointure (ici “geo” et “Year”).
mydata1 <- left_join(fish_16, bio_16_17)
print(mydata1)
## geo Capture Year SurfaceBio
## 1 Belgique 26860.00 2016 56055
## 2 Danemark 670212.83 2016 161251
## 3 Croatie 72865.34 2016 29172
## 4 Estonie 72421.83 2016 NA
## 5 Grèce NA 2016 NA
## 6 Finlande 164833.42 2016 NA
Pour le vérifier, on peut passer “geo” et “Year” comme variables de jointure:
mydata1 <- left_join(fish_16, bio_16_17, by=c("geo", "Year"))
print(mydata1)
## geo Capture Year SurfaceBio
## 1 Belgique 26860.00 2016 56055
## 2 Danemark 670212.83 2016 161251
## 3 Croatie 72865.34 2016 29172
## 4 Estonie 72421.83 2016 NA
## 5 Grèce NA 2016 NA
## 6 Finlande 164833.42 2016 NA
Les valeurs de Surface de cultures biologiques pour l’Estonie, la Grèce et la Finlande n’ont pas été renseignées, car elles sont relatives à l’année 2017. Elle ont donc été remplacées par des NA.
Remarque : puisque en l’absence de variable d’appariement, celle-ci se réalise, par défaut, sur l’ensemble des variables disponible, si l’on souhaite une jointure uniquement sur le pays, il est nécessaire de le préciser :
mydata1_bis <- left_join(fish_16, bio_16_17, by=c("geo"))
print(mydata1_bis)
## geo Capture Year.x SurfaceBio Year.y
## 1 Belgique 26860.00 2016 56055 2016
## 2 Danemark 670212.83 2016 161251 2016
## 3 Croatie 72865.34 2016 29172 2016
## 4 Estonie 72421.83 2016 160837 2017
## 5 Grèce NA 2016 280733 2017
## 6 Finlande 164833.42 2016 NA NA
On voit que dans ce cas, la variable Year a été conservé pour les deux jeux de données, ce qui est plus prudent !
Jointure à droite
mydata3 <- right_join(fish_16, bio_16_17)
print(mydata3)
## geo Capture Year SurfaceBio
## 1 Belgique 26860.00 2016 56055
## 2 Danemark 670212.83 2016 161251
## 3 Croatie 72865.34 2016 29172
## 4 Estonie NA 2017 160837
## 5 Grèce NA 2017 280733
## 6 Portugal NA 2017 216180
Ici, se sont les données de pêche qui n’ont pas été complétées puisqu’elle concernent l’année 2016 alors qu’il s’agit de l’année 2017 dans le tableau qui sert de référence (bio_16_17).
Jointure restreinte
mydata4 <- inner_join(fish_16, bio_16_17)
print(mydata4)
## geo Capture Year SurfaceBio
## 1 Belgique 26860.00 2016 56055
## 2 Danemark 670212.83 2016 161251
## 3 Croatie 72865.34 2016 29172
Jointure complète
mydata5 <- full_join(fish_16, bio_16_17)
print(mydata5)
## geo Capture Year SurfaceBio
## 1 Belgique 26860.00 2016 56055
## 2 Danemark 670212.83 2016 161251
## 3 Croatie 72865.34 2016 29172
## 4 Estonie 72421.83 2016 NA
## 5 Grèce NA 2016 NA
## 6 Finlande 164833.42 2016 NA
## 7 Estonie NA 2017 160837
## 8 Grèce NA 2017 280733
## 9 Portugal NA 2017 216180
Voilà ! J’espère que l’exploration de ces fonctions left_join(), right_join(), inner_join() et full_join(), avec une et plusieurs variables de jointure, vous a permis de mieux comprendre ce processus de fusion de deux jeux de données par leurs colonnes.
Si cet article vous a plu, ou vous a été utile, et si vous le souhaitez, vous pouvez soutenir ce blog en faisant un don sur sa page Tipeee 🙏
Crédits photos : OpenClipart-vectors
Merci encore Claire, tu nous délivres ainsi des maux de tête que nous vivons lors du traitement de nos données. Je tiens vraiment à vous féliciter.