Dans la pratique, les données sont hébergées sur différents serveurs et réparties dans de nombreux fichiers. Lorsque les informations dont vous avez besoin proviennent de plusieurs sources, il est essentiel de savoir les regrouper pour perdre le moins d'information possible et réaliser des appariements cohérents avec la structure de vos données.
Dans ce tutoriel, vous verrez :
- Comment fusionner des jeux de données horizontalement et verticalement
- Ce que sont les clés primaires et comment elles structurent vos données
- Les différents types de jointures (par ex. left join, inner join, full join) et comment choisir
- Un écueil fréquent à surveiller et comment le résoudre
Concaténer des jeux de données
À haut niveau, il existe deux façons de fusionner des jeux de données : vous pouvez ajouter des informations en ajoutant des lignes ou en ajoutant des colonnes à votre table. De manière générale, lorsque vous avez des jeux de données qui partagent le même jeu de colonnes ou le même jeu d'observations, vous pouvez les concaténer respectivement verticalement ou horizontalement. Voyons cela avec des exemples.
Ajouter des jeux de données verticalement
Lorsque vous avez plusieurs jeux de données avec le même ensemble de colonnes, vous pouvez concaténer l'un à l'autre verticalement. Autrement dit, en conservant les colonnes de votre table, vous pouvez ajouter des lignes. Avoir ces informations dans un seul fichier vous permettra d'agréger plus facilement et d'avoir une vue d'ensemble, sans jongler entre plusieurs fichiers au risque de vous y perdre.
Jeu de données 1
| Marque | Nb de modèles |
|---|---|
| Honda | 63 |
| BMW | 10 |
Jeu de données 2
| Marque | Nb de modèles |
|---|---|
| Ford | 26 |
| Tesla | 4 |
Attention : si une même observation figure dans plusieurs jeux de données et que vous les concaténez verticalement avec rbind(), vous obtiendrez des doublons dans votre table. Et bien que les deux jeux de données doivent partager le même ensemble de variables (c.-à-d. colonnes), elles n'ont pas besoin d'être dans le même ordre. Vérifiez-le vous‑même dans la console ci‑dessous !
Dans votre espace de travail, deux jeux de données dataset1 et dataset2 (vus ci‑dessus) sont disponibles. Essayez de réordonner les colonnes de dataset1. Appelez rbind() sur dataset1 et dataset2 ainsi que sur reordered_dataset1 et dataset2.
dataset1 <- data.frame(make = c("Honda", "BMW"),
num_models = c(63, 10))
dataset2 <- data.frame(make = c("Ford", "Tesla"),
num_models = c(26, 4))
# Ajouter des jeux de données verticalement
rbind(dataset1, dataset2)
# Réordonner les colonnes
reordered_dataset1 <- dataset1[, c(2, 1)]
# Vérifier que rbind() est robuste à l'ordre des colonnes
rbind(reordered_dataset1, dataset2)
Après rbind(), votre résultat doit contenir les informations sur les quatre marques dans une seule table comme ceci :
Jeu de données concaténé verticalement
| Marque | Nb de modèles |
|---|---|
| Honda | 63 |
| BMW | 10 |
| Ford | 26 |
| Tesla | 4 |
Commencez à apprendre R gratuitement
R niveau intermédiaire
Ajouter des jeux de données horizontalement
Lorsque vous avez des jeux de données représentant le même ensemble d'observations, vous pouvez les concaténer horizontalement. Cette fois, en conservant les lignes de votre table, vous pouvez ajouter des colonnes. Dans ce cas, vérifiez que l'ordre des observations est identique. Si vos jeux de données n'ont pas le même nombre de lignes, ou s'ils ont le même nombre de lignes mais dans un ordre différent, vous risquez d'apparier des colonnes de manière incohérente.
Poursuivons l'exemple précédent. Supposons que vous ayez deux fichiers : l'un contient la marque et le nombre de modèles uniques proposés, l'autre la marque et les ventes totales :
Nombre de modèles uniques proposés
| Marque | Nb de modèles |
|---|---|
| Honda | 63 |
| BMW | 10 |
| Ford | 26 |
| Tesla | 4 |
Ventes totales
| Marque | Ventes |
|---|---|
| Ford | 119157 |
| BMW | 25908 |
| Honda | 188328 |
| Tesla | 29975 |
Attention : si une même observation figure dans plusieurs jeux de données et que vous les concaténez horizontalement avec cbind(), vous obtiendrez des colonnes redondantes. Et même si les deux jeux de données contiennent des informations liées, l'ordre des lignes est crucial !
Dans la console ci‑dessous, appelez cbind() sur models et sales et affichez le résultat :
models <- data.frame(make = c("Honda", "BMW", "Ford", "Tesla"),
num_models = c(63, 10, 26, 4))
sales <- data.frame(make = c("Ford", "BMW", "Honda", "Tesla"),
sales = c(119157, 25908, 188328, 29975))
# Ajouter des jeux de données horizontalement
cbind(models, sales)
Vous devriez obtenir quelque chose comme ceci :
Modèles et ventes
| Marque | Nb de modèles | Marque | Ventes |
|---|---|---|---|
| Honda | 63 | Ford | 119157 |
| BMW | 10 | BMW | 25908 |
| Ford | 26 | Honda | 188328 |
| Tesla | 4 | Tesla | 29975 |
Voyez‑vous le problème ? Ces données ne sont pas « tidy » !
Selon les principes des données ordonnées présentés dans ce cours fondamental, chaque observation d'un jeu de données doit être représentée par une ligne unique. Et si vous ne disposez d'informations que pour certaines lignes d'un des jeux et souhaitez n'ajouter des informations que pour celles‑ci ? Autrement dit, que faire si vous voulez ajouter des colonnes d'un jeu de données à un autre, mais que ces jeux n'ont pas le même nombre d'observations ?
Clé primaire et clés étrangères
La première étape pour combiner des jeux de données consiste à repérer la clé primaire de votre table. La clé primaire est la colonne (ou l'ensemble de colonnes) qui identifie de façon unique chaque observation. Dans l'exemple des marques, du nombre de modèles uniques et des ventes totales, la clé primaire est la colonne make.
Nous pouvons maintenant effectuer des jointures, la méthode standard pour fusionner des jeux de données en une seule table.
Types de jointures
Il existe de nombreux types de jointures. Vous pouvez apprendre à enrichir les colonnes d'un jeu avec celles d'un autre via les jointures « mutating », à filtrer un jeu selon un autre avec les jointures de filtrage, et à manipuler des ensembles avec les opérations ensemblistes dans le cours Joining Data in R with dplyr. Voici les plus courantes.
left_join(x, y) : retourne toutes les lignes de x et toutes les colonnes de x et y. Les lignes de x sans correspondance dans y auront des valeurs NA dans les nouvelles colonnes. S'il existe plusieurs correspondances entre x et y, toutes les combinaisons sont retournées.
inner_join(x, y) : retourne toutes les lignes de x ayant une correspondance dans y, ainsi que toutes les colonnes de x et y. En cas de correspondances multiples, toutes les combinaisons sont retournées.
full_join(x, y) : retourne toutes les lignes et toutes les colonnes de x et y. En l'absence de correspondance, la fonction renvoie NA pour la valeur manquante.
Les jointures ci‑dessus sont des jointures « mutating », car elles combinent des variables issues de deux jeux de données.
Clés manquantes
Supposons que vous ayez deux jeux de données. Le premier, appelé size, contient des prénoms et leur taille de t‑shirt :
> size
name size
1 Tom M
2 Dan XL
3 Keil S
Le second, appelé color, contient les noms de famille, les préférences de couleur de t‑shirt et stocke certaines informations dans l'attribut row.names :
> color
surname color
Tom Jeon <NA>
Dan Smith Dark
Bob McLadden Light
Voyez ce qui peut poser problème ? Les jointures entre deux tables peuvent devenir complexes en présence de clés manquantes ou dupliquées. Dans cet exemple, les data frames de R stockent une information importante dans l'attribut row.names. Dans ce cas, vous ne pourrez pas accéder à la clé avec une fonction de jointure, car ces fonctions ne peuvent accéder qu'aux colonnes du data frame.
L'astuce pour résoudre facilement ce problème consiste à utiliser la fonction rownames_to_column() du package tibble. Elle renvoie une copie de votre jeu de données avec les noms de lignes ajoutés comme colonne. Le premier argument de rownames_to_column() est votre data frame, et le second est une chaîne indiquant le nom de la colonne à ajouter.
Essayez dans la console ci‑dessous. Les jeux size et color sont préchargés dans votre espace de travail.
color <- data.frame(surname = c("Jeon", "Smith", "McLadden"), color = c(NA, "Dark", "Light"))
row.names(color) <- c("Tom", "Dan", "Bob")
size <- data.frame(name = c("Tom", "Dan", "Keil"), size = c("M", "XL", "S"))
# Explorez ici !
Pour conclure
Dans le monde réel, les données peuvent être réparties entre de nombreux jeux et sous de multiples formats. Comme R est conçu pour travailler avec des tables uniques, manipuler et combiner des jeux de données en une table est une compétence indispensable. Suivez le parcours de compétences Importing & Cleaning Data with R et apprenez à analyser et combiner des données quel que soit le format. Consultez également le tutoriel R Data Import de DataCamp. Bon apprentissage !