Menu

Fusionner et joindre des data frames en R (merge, left_join)

Combiner des data frames par une clé commune : merge() pour les jointures interne, gauche, droite et complète, des noms de clés différents avec by.x/by.y, la famille de jointures de dplyr, et rbind() pour empiler des lignes.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Deux tableaux, une clé

Les vraies données vivent rarement dans un seul tableau. Les clients sont dans un data frame, leurs commandes dans un autre, et la question - « combien chaque client a-t-il dépensé ? » - a besoin des deux. Ce qui les relie est une clé : une colonne présente dans chaque tableau qui identifie la même entité. Combiner des tableaux sur une clé s'appelle une jointure (le mot de SQL) ou une fusion (le mot de R de base) ; même opération.

Voici la paire de tableaux qu'utilise le reste de cette page. Note que le client 5 a passé une commande mais n'est pas dans le tableau des clients, et que les clients 2 et 4 n'ont jamais commandé :

Les décalages sont volontaires - ce qu'une jointure fait des lignes non appariées est précisément ce qui distingue les types de jointures.

merge() : jointure interne par défaut

merge(x, y, by = "key") apparie les lignes dont les clés sont égales et colle leurs colonnes ensemble. Par défaut il ne garde que les clés présentes dans les deux tableaux - une jointure interne :

Trois lignes reviennent. Ana apparaît deux fois - elle a deux commandes, et une jointure produit une ligne de sortie par paire appariée. Ben et Dana ont disparu (aucune commande), tout comme la commande mystérieuse du client 5 (aucun client). Une jointure interne écarte silencieusement les lignes non appariées des deux tableaux - exactement ce qu'il faut quand seules les paires complètes t'intéressent, et un bug de perte de données silencieuse dans le cas contraire.

Jointures gauche, droite et complète : all.x, all.y, all

Pour garder les lignes non appariées, dis quelles lignes sont sacrées. all.x = TRUE garde chaque ligne du premier tableau - la jointure gauche, la plus utilisée en pratique :

Maintenant Ben et Dana survivent, avec NA dans amount - « ce client existe ; aucune commande appariée ». Ces NA sont informatifs, pas des déchets : is.na(result$amount) est exactement la liste des clients qui n'ont jamais commandé (la doc sur les valeurs manquantes explique comment travailler avec). Les variantes restantes sont la même idée pointée ailleurs : all.y = TRUE garde chaque ligne du second tableau (jointure droite - la commande du client inconnu 5 survivrait avec NA dans name), et all = TRUE garde tout des deux côtés (jointure complète).

Choisis en te demandant : quelles lignes n'ai-je pas le droit de perdre ? Enrichir un tableau maître avec des données de référence - jointure gauche, tableau maître en premier. Auditer dans les deux sens - jointure complète.

Noms de clés différents : by.x et by.y

Les tableaux s'accordent rarement sur le nommage - id dans l'un, customer_id dans l'autre. Ne renomme pas ; indique les deux noms à merge() :

La sortie conserve le nom de clé du premier tableau. Point connexe : si les deux tableaux partagent des noms de colonnes hors clé (les deux ont un date, disons), merge leur ajoute les suffixes date.x et date.y - renomme-les rapidement, ils se lisent affreusement.

Les jointures dplyr

dplyr donne à chaque type de jointure son propre verbe, si bien que l'intention est dans le nom de la fonction plutôt que dans des arguments-drapeaux (statique ; le bac à sable n'exécute que du R de base) :

library(dplyr)

left_join(customers, orders, by = "id")
inner_join(customers, orders, by = "id")
full_join(customers, orders, by = "id")
left_join(customers, orders, by = c("id" = "customer_id"))  # different names

Au-delà de la lisibilité, left_join() préserve l'ordre des lignes du premier tableau (merge() retrie par clé) et avertit bruyamment en cas de correspondances multiples des deux côtés - voir l'intro à dplyr pour la famille de verbes.

Le membre sous-estimé est anti_join() : il renvoie les lignes du premier tableau qui n'ont aucune correspondance dans le second - aucune colonne ajoutée, juste les restes :

anti_join(customers, orders, by = "id")   # customers who never ordered

Cette question - « quelles lignes n'ont pas trouvé de correspondance ? » - revient constamment en nettoyage de données (identifiants non appariés, enregistrements orphelins, recherches infructueuses), et anti_join() y répond en un appel là où R de base a besoin de customers[!(customers$id %in% orders$id), ].

Empiler des lignes : rbind()

Joindre combine les colonnes de deux tableaux. Quand tu as plutôt deux lots du même genre de lignes - les commandes de janvier et celles de février - tu les empiles avec rbind() :

L'exigence est stricte : les deux data frames doivent avoir les mêmes noms de colonnes (dans n'importe quel ordre - rbind apparie par nom). Une colonne manquante ou en trop est une erreur, pas un remplissage par NA. Quand les lots ont des colonnes divergentes, bind_rows() de dplyr est plus tolérant - il aligne par nom et comble les trous avec NA.

L'explosion des clés en double

L'accident de jointure classique : des clés que tu croyais uniques, mais qui ne le sont pas - dans les deux tableaux. Chaque correspondance s'apparie avec chaque correspondance, multipliant les lignes :

Deux lignes jointes à deux lignes en donnent quatre - chaque x apparié à chaque y. Sur de vraies données, c'est ainsi qu'un tableau de 10 000 lignes devient 3 millions de lignes et un chiffre d'affaires total doublé. merge() fait ça en silence. La défense est une habitude : avant de joindre, vérifie la clé que tu supposes unique - anyDuplicated(customers$id) devrait valoir 0 - et après la jointure, contrôle nrow() par rapport à ce que tu attendais.

Ce que tu retiens

  • merge(x, y, by = "key") est une jointure interne - les lignes non appariées disparaissent silencieusement.
  • all.x = TRUE (gauche), all.y = TRUE (droite), all = TRUE (complète) gardent les lignes non appariées en comblant avec NA.
  • Noms de clés différents : by.x / by.y en base, by = c("a" = "b") en dplyr.
  • dplyr nomme chaque jointure ; anti_join() - les lignes qui n'ont pas trouvé de correspondance - est la sous-estimée.
  • rbind() empile des tableaux de même forme ; les colonnes doivent correspondre par nom.
  • Les clés en double multiplient les lignes en silence - vérifie anyDuplicated() avant, nrow() après.

Prochaine étape : remettre en forme entre formats large et long avec pivot_longer() et pivot_wider().

Questions fréquentes

Comment fusionner deux data frames en R ?

Utilise merge(x, y, by = "key") avec la colonne clé commune. Par défaut il réalise une jointure interne - seules les lignes dont la clé apparaît dans les deux data frames survivent. Ajoute all.x = TRUE pour une jointure gauche, all.y = TRUE pour une jointure droite, ou all = TRUE pour une jointure complète.

Comment faire une jointure gauche en R ?

R de base : merge(x, y, by = "key", all.x = TRUE) garde chaque ligne de x et remplit les colonnes de y avec NA là où aucune correspondance n'existe. dplyr : left_join(x, y, by = "key") - même résultat, et il préserve aussi l'ordre des lignes d'origine de x, ce que merge() ne fait pas.

Comment fusionner des data frames quand les colonnes clés ont des noms différents ?

Indique les deux noms à merge() : merge(x, y, by.x = "id", by.y = "customer_id"). En dplyr l'équivalent est left_join(x, y, by = c("id" = "customer_id")), ou avec le helper moderne, by = join_by(id == customer_id).

Quelle est la différence entre merge et rbind en R ?

Ils combinent dans des dimensions différentes. merge() apparie les lignes de deux tableaux par une clé et combine leurs colonnes - une jointure. rbind() empile les lignes d'un tableau sous celles d'un autre - les deux doivent avoir les mêmes noms de colonnes. Des fichiers mensuels aux colonnes identiques appellent rbind() ; clients plus commandes appelle merge().

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER