Fusionner des trames de données dans R : correspondance complète et partielle
⚡ Résumé intelligent
La fusion de data frames en R consiste à joindre deux tables en fonction d'une ou plusieurs colonnes clés communes. La fonction `merge()` prend en charge les jointures internes, externes gauches, externes droites et complètes. Ce tutoriel illustre une correspondance complète et une correspondance partielle.

Très souvent, nous disposons de données provenant de plusieurs sources. Pour effectuer une analyse, nous devons fusionner deux trames de données avec une ou plusieurs variables clés communes.
Types de fusion (jointure) en R
Avant d'examiner les exemples, il est utile de savoir que la fonction `merge()` effectue tous les types de jointures attendus par un utilisateur SQL. Son comportement est déterminé par les arguments `all`, `all.x` et `all.y`, et non par un nom de fonction différent.
| Type de jointure | Rangées conservées | appel à merge() | équivalent de dplyr |
|---|---|---|---|
| Jointure interne (par défaut) | Seules les clés présentes dans les deux cadres | fusionner(x, y, par = « k ») | jointure_intérieure(x, y, par = "k") |
| Jointure externe gauche | Toutes les lignes de x, NA où y n'a pas de correspondance | fusionner(x, y, par = "k", all.x = VRAI) | jointure_gauche(x, y, par = "k") |
| Jointure externe droite | Toutes les lignes de y, NA où x n'a pas de correspondance | fusionner(x, y, par = "k", all.y = TRUE) | jointure_droite(x, y, par = "k") |
| Jointure externe complète | Chaque rangée des deux cadres | fusionner(x, y, par = « k », tout = VRAI) | jointure_complète(x, y, par = "k") |
| Jointure croisée | Chaque combinaison de lignes | fusionner(x, y, par = NULL) | jointure_croisée(x, y) |
Deux détails sont à retenir avant le premier appel :
- Omettre la colonne « by » permet à R de fusionner chaque nom de colonne que les deux cadres partagent, ce qui est rarement ce que l'on souhaite.
- La fonction merge() trie le résultat selon la colonne clé ; passez sort = FALSE pour conserver l’ordre d’entrée.
Correspondance parfaite
Une correspondance exacte ne renvoie que les valeurs ayant un équivalent dans la table de destination. Les lignes sans correspondance sont supprimées du nouveau tableau de données. À l'inverse, une correspondance partielle conserve ces lignes et remplace les valeurs manquantes par NA.
Nous verrons un simple jointure intérieure. Le mot-clé de jointure interne sélectionne les enregistrements dont les valeurs correspondent dans les deux tables. Pour joindre deux ensembles de données, nous pouvons utiliser la fonction merge(). Nous utiliserons trois arguments :
merge(x, y, by.x = x, by.y = y) Arguments: -x: The origin data frame -y: The data frame to merge -by.x: The column used for merging in x data frame. Column x to merge on -by.y: The column used for merging in y data frame. Column y to merge on
Exemple :
Créer le premier ensemble de données avec des variables
- nom de famille
- nationalité
Créer un deuxième ensemble de données avec des variables
- nom de famille
- films
La variable clé commune est le nom de famille. Nous pouvons fusionner les deux trames de données et vérifiez que la dimensionnalité est de 7×3.
Nous ajoutons stringsAsFactors=FALSE dans le dataframe car nous ne voulons pas R pour convertir les chaînes en un facteurLa variable doit rester un vecteur de caractères. Depuis R 4.0.0, c'est le comportement par défaut de la fonction `data.frame()`, l'argument est donc optionnel dans le nouveau code et sans conséquence dans l'ancien.
# Create origin dataframe( producers <- data.frame( surname = c("Spielberg","Scorsese","Hitchcock","Tarantino","Polanski"), nationality = c("US","US","UK","US","Poland"), stringsAsFactors=FALSE) # Create destination dataframe movies <- data.frame( surname = c("Spielberg", "Scorsese", "Hitchcock", "Hitchcock", "Spielberg", "Tarantino", "Polanski"), title = c("Super 8", "Taxi Driver", "Psycho", "North by Northwest", "Catch Me If You Can", "Reservoir Dogs","Chinatown"), stringsAsFactors=FALSE) # Merge two datasets m1 <- merge(producers, movies, by.x = "surname") m1 dim(m1)
Sortie :
surname nationality title 1 Hitchcock UK Psycho 2 Hitchcock UK North by Northwest 3 Polanski Poland Chinatown 4 Scorsese US Taxi Driver 5 Spielberg US Super 8 6 Spielberg US Catch Me If You Can 7 Tarantino US Reservoir Dogs
Fusionnons les trames de données lorsque les variables clés communes ont des noms différents.
Nous changeons le nom de famille en nom dans la trame de données du film. Nous utilisons la fonction identique (x1, x2) pour vérifier si les deux trames de données sont identiques.
# Change name of ` movies ` dataframe colnames(movies)[colnames(movies) == 'surname'] <- 'name' # Merge with different key value m2 <- merge(producers, movies, by.x = "surname", by.y = "name") # Print head of the data head(m2)
Sortie :
##surname nationality title ## 1 Hitchcock UK Psycho ## 2 Hitchcock UK North by Northwest ## 3 Polanski Poland Chinatown ## 4 Scorsese US Taxi Driver ## 5 Spielberg US Super 8 ## 6 Spielberg US Catch Me If You Can
# Check if data are identical
identical(m1, m2)
Sortie :
## [1] TRUE
Cela montre que l'opération de fusion est effectuée même si les noms de colonnes sont différents.
Correspondance partielle
La jointure interne ci-dessus a discrètement supprimé tout ce qui n'avait pas de contrepartie. Il n'est pas surprenant que deux dataframes n'aient pas les mêmes variables clés communes. correspondance complète, la trame de données renvoie uniquement lignes trouvées dans les trames de données x et y. Avec fusion partielle, il est possible de conserver les lignes sans lignes correspondantes dans l'autre bloc de données. Ces lignes auront NA dans les colonnes qui sont généralement remplies de valeurs de y. Nous pouvons le faire en définissant all.x= TRUE.
Par exemple, nous pouvons ajouter un nouveau producteur, Lucas, au dataframe `productor` sans que les références aux films soient présentes dans le dataframe `movies`. Si nous définissons `all.x = FALSE`, R ne fusionnera que les valeurs correspondantes des deux dataframes. Dans notre cas, le producteur Lucas ne sera pas inclus dans le résultat, car il est absent de l'un des dataframes.
Voyons la dimension de chaque sortie lorsque nous spécifions all.x= TRUE et lorsque nous ne le faisons pas.
# Create a new producer add_producer <- c('Lucas', 'US') # Append it to the ` producer` dataframe producers <- rbind(producers, add_producer) # Use a partial merge m3 <-merge(producers, movies, by.x = "surname", by.y = "name", all.x = TRUE) m3
Sortie :
La sortie console ci-dessous affiche la ligne Lucas supplémentaire, avec NA remplaçant le titre de film manquant.
# Compare the dimension of each data frame
dim(m1)
Sortie :
## [1] 7 3
dim(m2)
Sortie :
## [1] 7 3
dim(m3)
Sortie :
## [1] 8 3
Comme on peut le constater, le nouveau tableau de données est de dimension 8×3, contre 7×3 pour m1 et m2. R remplit la colonne « title » avec la valeur NA pour Lucas, le producteur qui n’a pas de ligne correspondante dans le tableau de données « movies ».
merge() vs dplyr Joins en R
R de base résout chaque jointure avec une seule fonction et un ensemble d'indicateurs. déplyr Le package attribue plutôt à chaque jointure son propre verbe, ce que de nombreuses équipes trouvent plus facile à lire dans un pipeline.
| Critères | Fusion de base() | dplyr rejoint |
|---|---|---|
| Choisir la jonction | tous.x / tous.y / tous les drapeaux | Nommé dans le verbe : left_join(), full_join() |
| Ordre des lignes | Trié par clé sauf si sort = FALSE | L'ordre du tableau de gauche est préservé |
| Vitesse sur les grands châssis | Ralentissez | Généralement plus rapide |
| Colonne clé manquante | Échoue en retard ou fusionne sur les mauvaises colonnes | Erreurs immédiatement |
| Dépendances | Base R, rien à installer | Nécessite le package dplyr |
Les deux fusions présentées ci-dessus se traduisent directement en verbes dplyr :
library(dplyr) # Same inner join as merge(producers, movies, by.x = "surname", by.y = "name") m4 <- inner_join(producers, movies, by = c("surname" = "name")) # Same partial merge as all.x = TRUE m5 <- left_join(producers, movies, by = c("surname" = "name"))
La fonction `merge()` de base est plus sûre dans un package sans dépendances. `dplyr` est préférable pour une analyse interactive, où la lisibilité et la rapidité sont primordiales.
Erreurs de fusion courantes en R et comment les corriger
La plupart des problèmes de fusion se manifestent par un nombre de lignes inattendu plutôt que par un message d'erreur ; il est donc judicieux de prendre l'habitude de vérifier dim() après chaque jointure.
- Le résultat comporte plus de lignes que chacune des entrées. Une clé présente dans les deux cadres génère une jointure plusieurs-à-plusieurs, et R renvoie toutes les combinaisons possibles. Examinez les clés avec `table(duplicated(x$k))` avant la fusion.
- Le résultat est vide. Les colonnes clés diffèrent généralement par leur type, ou l'une d'elles contient des espaces en fin de ligne. Exécutez la fonction str() sur les deux cadres et nettoyez la clé avec trimws() avant la fusion.
- Les colonnes sont renvoyées sous la forme title.x et title.y. Les deux cadres contiennent une colonne non clé portant le même nom. Utilisez `suffixes = c("_producer", "_film")` pour rendre l'origine évidente.
- Les rangées ne sont plus dans leur ordre initial. La fonction merge() trie par défaut selon la clé. Ajoutez sort = FALSE, ou utilisez un type explicite après.
- Une comparaison essentielle échoue sur plusieurs points. Comparez les caractères, pas les niveaux de facteurs : enveloppez la clé dans as.character() avant de fusionner les cadres créés sous d’anciennes valeurs par défaut de R.
Lorsqu'une même fusion doit être exécutée à plusieurs reprises, enveloppez-la dans un fonction définie par l'utilisateur Ainsi, les arguments ne peuvent pas dériver d'une exécution à l'autre.

