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.

  • (I.e. Colonnes clés : La fonction merge() effectue une jointure sur by, ou sur by.x et by.y lorsque la clé porte un nom différent dans chaque trame.
  • 🔗 Match complet : La jointure interne par défaut ne conserve que les lignes dont la clé apparaît dans les deux cadres de données.
  • 🧩 Correspondance partielle : Définir all.x = TRUE conserve chaque ligne de la première trame et remplit les espaces vides avec NA.
  • (I.e. Vérification des dimensions : Comparez dim() avant et après une fusion pour repérer les lignes perdues ou dupliquées par la jointure.
  • ⚙️ Contrôle de la jonction : Les options all, all.x et all.y permettent de sélectionner un comportement interne, gauche, droite ou externe complet.
  • Alternative moderne : dplyr nomme chaque jointure dans le verbe lui-même et préserve l'ordre des lignes d'origine.

Fusionner des trames de données dans R

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.

Sortie console de la fusion partielle montrant Lucas avec NA dans la colonne titre

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

FAQ

R effectue une fusion sur chaque nom de colonne commun aux deux cadres. Avec une seule colonne commune, c'est pratique ; avec plusieurs, cela restreint silencieusement le résultat ; et sans aucune, cela effectue une jointure croisée. Nommer explicitement la clé permet d'éviter ces trois problèmes.

N'utilisez pas une seule fonction `merge()`. Enchaînez les appels ou réduisez la liste avec `Reduce(function(x, y) merge(x, y, by = "k"), list(df1, df2, df3))`. Vérifiez le nombre de lignes après chaque étape, car les clés dupliquées s'accumulent rapidement.

Les deux cadres contenaient une colonne non clé portant le même nom ; R les distingue donc. Utilisez `suffixes = c("_producer", "_film")` pour nommer les copies de manière explicite, ou supprimez la colonne redondante avant la fusion.

Non. Par défaut, la fonction merge() trie le résultat selon la colonne clé. Passez sort = FALSE pour conserver l'ordre d'entrée, ou utilisez un déplyr jointure, qui préserve l'ordre du cadre de gauche.

Fournissez un vecteur : `merge(x, y, by = c("surname", "year"))`. Si les noms diffèrent, transmettez les vecteurs correspondants à `by.x` et `by.y`. Les deux vecteurs doivent lister les colonnes dans le même ordre.

Utilisez by = « row.names », ou la forme abrégée by = 0. R ajoute les noms de lignes dans une colonne appelée Row.names, que vous voudrez généralement renommer ou supprimer avant de poursuivre l'analyse.

Décrivez les deux cadres et le nombre de lignes ; un assistant IA indiquera la présence de clés dupliquées comme cause probable et suggérera une vérification avec la fonction `duplicated()`. Confirmez le diagnostic avec vos propres données avant de modifier la jointure.

Oui. RStudio La version 2023.09.0 et les versions ultérieures de Windows Desktop proposent une option d'activation. Copilote GitHub Intégration qui génère une fusion à partir d'un commentaire. Vérifiez le type de jointure choisi, car un paramètre incorrect modifie silencieusement le nombre de lignes.

Résumez cet article avec :