Tutoriel dplyr en R : Fusionner et joindre des données avec des exemples

⚡ Résumé intelligent

dplyr permet de fusionner des data frames en R grâce à quatre fonctions : left_join(), right_join(), inner_join() et full_join(). Son package associé, tidyr, remodèle ensuite le résultat de la fusion à l’aide de gather(), spread(), separate() et unite().

  • 🔗 Mutation des jointures : left_join() conserve chaque ligne de la table d'origine et right_join() conserve chaque ligne de la table de destination.
  • (I.e. Contrôle du match : inner_join() supprime les lignes non appariées, tandis que full_join() conserve les deux côtés et remplit les lacunes avec NA.
  • 🇧🇷 Clés composites : Passer par = c(“ID”, “année”) chaque fois qu’une seule colonne n’identifie pas une ligne de manière unique.
  • (I.e. Reshaping: gather() transforme un tableau large en tableau long et spread() le transforme en tableau court, gardezping une variable par colonne.
  • ✂️ Division et union : La fonction separate() divise une colonne en fonction d'un délimiteur, tandis que la fonction unite() concatène les colonnes en une seule.
  • ⚠️ Note de version : pivot_longer(), pivot_wider() et separate_wider_delim() remplacent l'ancienne fonction tidyr reshaping fonctions.

Dplyr dans R : Fusionner et joindre des données

Introduction à l'analyse des données

Avant toute adhésion ou redistributionping Le verbe est logique, il permet de voir où se situe la manipulation des données. Analyse de données peut être divisée en trois parties :

  • extraction: Premièrement, nous devons collecter les données provenant de nombreuses sources et les combiner.
  • Transformez: Cette étape implique la manipulation des données. Une fois que nous avons consolidé toutes les sources de données, nous pouvons commencer à nettoyer les données.
  • Visualisez: La dernière étape consiste à visualiser nos données pour vérifier les irrégularités.

Le schéma ci-dessous illustre comment les trois étapes sont reliées.

Processus d'analyse de données en trois étapes illustrant extraction, transformation et visualisation
Processus d'analyse des données

L'un des principaux défis des data scientists réside dans la manipulation des données. Celles-ci sont rarement disponibles dans le format souhaité. Les data scientists doivent consacrer au moins la moitié de leur temps au nettoyage et à la manipulation des données. Il s'agit d'une des tâches les plus cruciales de leur métier. Si le processus de manipulation des données n'est pas complet, précis et rigoureux, le modèle ne fonctionnera pas correctement.

R dplyr

R possède un package appelé dplyr qui gère la transformation des données. Il s'articule autour d'un petit ensemble de fonctions essentielles — filter(), select(), arrange(), mutate() et summarise() — ainsi que d'une famille de fonctions de jointure. Une fois les données structurées, ggplot2 peut les visualiser.

Nous apprendrons à utiliser le package dplyr pour manipuler un Trame de donnéesSi R n'est pas encore installé, suivez les instructions. Étapes de configuration de R et RStudio, puis exécutez install.packages(“dplyr”).

Fusionner des données avec dplyr

dplyr fournit un moyen agréable et pratique de combiner des ensembles de données. Nous pouvons disposer de nombreuses sources de données d’entrée et, à un moment donné, nous devons les combiner. Une jointure avec dplyr ajoute des variables à droite de l'ensemble de données d'origine.

dplyr se joint

Voici quatre types importants de jointures utilisés dans dplyr pour fusionner deux ensembles de données. Toutes prennent les mêmes arguments (les deux tables et la clé) et diffèrent uniquement par les lignes non appariées conservées :

Fonction Objectif Arguments Plusieurs clés
joint gauche() Fusionnez deux ensembles de données. Conserver toutes les observations de la table d'origine x, y, par = « ID » x, y, by = c("ID", "ID2")
right_join() Fusionnez deux ensembles de données. Conserver toutes les observations de la table de destination x, y, par = « ID » x, y, by = c("ID", "ID2")
jointure interne() Fusionner deux ensembles de données. Exclure toutes les lignes non appariées. x, y, par = « ID » x, y, by = c("ID", "ID2")
full_join() Fusionnez deux ensembles de données. Conservez toutes les observations. x, y, par = « ID » x, y, by = c("ID", "ID2")

Ces quatre verbes correspondent aux jointures GAUCHE, DROITE, INTÉRIEURE et EXTÉRIEURE COMPLÈTE de SQL. R de base parvient aux mêmes résultats grâce aux arguments all, all.x et all.y de fusionner().

Nous allons étudier tous les types de jointures à travers un exemple simple.

Tout d'abord, nous créons deux ensembles de données. Le tableau 1 contient deux variables, ID et y, tandis que le tableau 2 rassemble ID et z. Dans chaque cas, nous avons besoin d'un paire de clés variable. Dans notre cas, l'identification est notre clé La fonction recherchera les valeurs identiques dans les deux tableaux et associera les valeurs renvoyées à droite du tableau 1. La figure ci-dessous montre les deux tableaux côte à côte.

Deux exemples de tables partageant une colonne de clé ID avant une fusion dplyr

library(dplyr)
df_primary <- tribble(
  ~ID, ~y,
   "A", 5,
   "B", 5,
   "C", 8,
   "D", 0,
  "F", 9)
df_secondary <- tribble(
  ~ID, ~z,
   "A", 30,
   "B", 21,
   "C", 22,
   "D", 25,
   "E", 29)

dplyr left_join()

La méthode la plus courante pour fusionner deux ensembles de données consiste à utiliser la fonction `left_join()`. L'image ci-dessous montre que les paires de clés correspondent aux lignes A, B, C et D, tandis que les lignes E et F sont exclues. Avec `left_join()`, toutes les lignes de la table d'origine sont conservées, et celles qui n'ont pas de paire de clés correspondante dans la table de destination sont ignorées. Dans notre exemple, la valeur E n'existe pas dans la table 1 ; la ligne correspondante est donc supprimée. La valeur F provient de la table d'origine ; elle est donc conservée après l'application de `left_join()` et la valeur NA est renvoyée dans la colonne z.

Exemple de dplyr left_join()

Le diagramme ci-dessous reproduit ce qui se passe lors d'une jointure gauche (left_join()).

Diagramme de dplyr left_join keeping chaque ligne du tableau d'origine et la suppressionping ID E

left_join(df_primary, df_secondary, by ='ID')

Sortie :

## 
# A tibble: 5 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>		
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     F     9    NA

Notez que lorsque les deux tables comportent une colonne portant le même nom, dplyr les distingue grâce aux suffixes .x et .y indiqués ci-dessus.

dplyr jointure_droite()

La fonction right_join() fonctionne exactement comme left_join(). La seule différence est la ligne supprimée. La valeur E, disponible dans la trame de données de destination, existe dans la nouvelle table et prend la valeur NA pour la colonne y.

Exemple de dplyr right_join()

Le schéma ci-dessous montre l'image miroir.

Diagramme de dplyr right_join keeping chaque ligne du tableau de destination et la suppressionping ID F

right_join(df_primary, df_secondary, by = 'ID')

Sortie :

##
# A tibble: 5 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     E    NA    29

jointure interne dplyr()

Lorsque les observations non appariées sont totalement inutiles, nous pouvons retourner uniquement les lignes qui existent dans tous les deux jeux de données. C'est le bon choix lorsque nous avons besoin d'un jeu de données complet et que nous ne voulons pas imputer les valeurs manquantes avec la moyenne ou la médiane.

La fonction inner_join() s'avère utile ici. Elle exclut les lignes non appariées des deux côtés.

Exemple de dplyr inner_join()

Le diagramme ci-dessous met en évidence les quatre identifiants qui survivent à la jointure.

Diagramme de la fonction inner_join de dplyr ne renvoyant que les quatre identifiants présents dans les deux tables.

inner_join(df_primary, df_secondary, by ='ID')

Sortie :

## 
# A tibble: 4 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25

dplyr full_join()

Enfin, la fonction full_join() conserve toutes les observations et remplace les valeurs manquantes par NA.

Exemple de dplyr full_join()

Le diagramme ci-dessous montre tous les identifiants des deux tables qui ont survécu à la jointure.

Diagramme de dplyr full_join keeping Les six identifiants et les valeurs manquantes remplacées par NA

full_join(df_primary, df_secondary, by = 'ID')

Sortie :

## # A tibble: 6 x 3
##      ID   y.x   y.y
##   <chr> <dbl> <dbl>
## 1     A     5    30
## 2     B     5    21
## 3     C     8    22
## 4     D     0    25
## 5     F     9    NA
## 6     E    NA    29

Plusieurs paires de clés

Enfin, il est important de noter que notre ensemble de données peut comporter plusieurs clés. Prenons l'exemple suivant, où nous avons des années et une liste de produits achetés par le client. La capture d'écran ci-dessous illustre les deux tables ainsi que les colonnes « ID » et « Année » qui, ensemble, identifient une ligne.

Deux cadres de données partageant une clé composite constituée des colonnes ID et année

Si nous fusionnons les deux tables uniquement sur l'ID, chaque année est comparée à toutes les autres et le nombre de lignes devient exponentiel. Pour remédier à ce problème, nous pouvons utiliser deux paires de clés : l'ID et l'année, présentes dans les deux ensembles de données. Le code suivant permet de fusionner les tables 1 et 2 :

df_primary <- tribble(
  ~ID, ~year, ~items,
  "A", 2015,3,
  "A", 2016,7,
  "A", 2017,6,
  "B", 2015,4,
  "B", 2016,8,
  "B", 2017,7,
  "C", 2015,4,
  "C", 2016,6,
  "C", 2017,6)
df_secondary <- tribble(
  ~ID, ~year, ~prices,
  "A", 2015,9,
  "A", 2016,8,
  "A", 2017,12,
  "B", 2015,13,
  "B", 2016,14,
  "B", 2017,6,
  "C", 2015,15,
  "C", 2016,15,
  "C", 2017,13)
left_join(df_primary, df_secondary, by = c('ID', 'year'))

Sortie :

## # A tibble: 9 x 4
##      ID  year items prices
##   <chr> <dbl> <dbl>  <dbl>
## 1     A  2015     3      9
## 2     A  2016     7      8
## 3     A  2017     6     12
## 4     B  2015     4     13
## 5     B  2016     8     14
## 6     B  2017     7      6
## 7     C  2015     4     15
## 8     C  2016     6     15
## 9     C  2017     6     13

Depuis dplyr 1.1.0 (janvier 2023), la même clé peut s'écrire sous la forme join_by(ID, year), et dplyr signale désormais les correspondances inattendues de type plusieurs-à-plusieurs. dplyr 1.1.0 rejoint l'annonce explique.

Fonctions de nettoyage des données dans R

La fusion ne résout que la moitié du problème, car le tableau combiné doit encore être restructuré. Voici les quatre fonctions importantes pour nettoyer les données :

Fonction Objectif Arguments
rassembler() Transformez les données de large en long (données, clé, valeur, na.rm = FALSE)
propagé() Transformez les données de longues en larges (données, clé, valeur)
séparé() Diviser une variable en deux (données, colonne, dans, sep = "", supprimer = VRAI)
unir() Unir deux variables en une seule (données, col, conc, sep = "", supprimer = VRAI)

Note de version : Dans tidyr 1.0.0, les fonctions `gather()` et `spread()` ont été remplacées par `pivot_longer()` et `pivot_wider()`, et dans tidyr 1.3.0, `separate()` par la famille `separate_wider_delim()`. Les fonctions obsolètes restent fonctionnelles ; par conséquent, tous les exemples ci-dessous fonctionnent. Toutefois, il est recommandé d'utiliser de préférence les nouvelles familles de fonctions présentées dans la documentation. vignette pivotante de Tidyr.unite() reste actuel.

Nous utilisons le package tidyr, qui fait partie de la collection tidyverse, pour manipuler, nettoyer et visualiser les données. Si R a été installé avec Anaconda, le package est déjà disponible depuis [lien manquant]. https://anaconda.org/r/r-tidyr.

S'il n'est pas déjà installé, entrez la commande suivante pour installer Tidyr :

install.packages("tidyr")

rassembler()

L'objectif de la fonction gather() est de transformer les données d'un format large à un format long.

Syntaxe

gather(data, key, value, na.rm = FALSE)
Arguments:
-data: The data frame used to reshape the dataset 
-key: Name of the new column created
-value: Select the columns used to fill the key column
-na.rm: Remove missing values. FALSE by default

Exemple

Ci-dessous, nous pouvons visualiser le concept de reshaping Nous souhaitons créer une seule colonne nommée « croissance », remplie par les lignes des variables trimestrielles. La figure ci-dessous montre le tableau large à gauche et le tableau long restructuré à droite.

Reshaping convertir un tableau trimestriel large au format long grâce à la fonction de regroupement de tidyr

library(tidyr)
# Create a messy dataset
messy <- data.frame(
  country = c("A", "B", "C"),
  q1_2017 = c(0.03, 0.05, 0.01),
  q2_2017 = c(0.05, 0.07, 0.02),
  q3_2017 = c(0.04, 0.05, 0.01),
  q4_2017 = c(0.03, 0.02, 0.04))
messy

Sortie :

##   country q1_2017 q2_2017 q3_2017 q4_2017
## 1       A    0.03    0.05    0.04    0.03
## 2       B    0.05    0.07    0.05    0.02
## 3       C    0.01    0.02    0.01    0.04
# Reshape the data
tidier <-messy %>%
gather(quarter, growth, q1_2017:q4_2017)
tidier

Sortie :

##    country quarter growth
## 1        A q1_2017   0.03
## 2        B q1_2017   0.05
## 3        C q1_2017   0.01
## 4        A q2_2017   0.05
## 5        B q2_2017   0.07
## 6        C q2_2017   0.02
## 7        A q3_2017   0.04
## 8        B q3_2017   0.05
## 9        C q3_2017   0.01
## 10       A q4_2017   0.03
## 11       B q4_2017   0.02
## 12       C q4_2017   0.04

Dans la fonction `gather()`, nous créons deux nouvelles variables, `quarter` et `growth`, car notre jeu de données d'origine comporte une variable de groupe, `country`, et les paires clé-valeur. Dans tidyr 1.0.0 et versions ultérieures, la même opération de restructuration s'écrit `pivot_longer(messy, cols = q1_2017:q4_2017, names_to = “quarter”, values_to = “growth”)`.

propagé()

La fonction spread() fait l'inverse de gather().

Syntaxe

spread(data, key, value)
arguments: 
data: The data frame used to reshape the dataset
key: Column to reshape long to wide
value: Rows used to fill the new column

Exemple

Nous pouvons transformer l'ensemble de données plus propre en un ensemble désordonné avec spread().

# Reshape the data
messy_1 <- tidier %>%
  spread(quarter, growth) 
messy_1

Sortie :

##   country q1_2017 q2_2017 q3_2017 q4_2017
## 1       A    0.03    0.05    0.04    0.03
## 2       B    0.05    0.07    0.05    0.02
## 3       C    0.01    0.02    0.01    0.04

L'équivalent moderne est pivot_wider(tidier, names_from = quarter, values_from = growth).

séparé()

La fonction separate() divise une colonne en deux selon un séparateur. Cette fonction est utile lorsque la variable est une date. Notre analyse peut nécessiter de se concentrer sur le mois et l'année, et nous souhaitons alors séparer la colonne en deux nouvelles variables.

Syntaxe

separate(data, col, into, sep= "", remove = TRUE)
arguments:
-data: The data frame used to reshape the dataset 
-col: The column to split
-into: The name of the new variables
-sep: Indicates the symbol used that separates the variable, i.e.:  "-", "_", "&"
-remove: Remove the old column. By default sets to TRUE.

Exemple

Nous pouvons diviser le trimestre de l’année dans l’ensemble de données le plus ordonné en appliquant la fonction Separate().

separate_tidier <-tidier %>%
separate(quarter, c("Qrt", "year"), sep ="_")
head(separate_tidier)

Sortie :

##   country Qrt year growth
## 1       A  q1 2017   0.03
## 2       B  q1 2017   0.05
## 3       C  q1 2017   0.01
## 4       A  q2 2017   0.05
## 5       B  q2 2017   0.07
## 6       C  q2 2017   0.02

unir()

La fonction unite() concatène deux colonnes en une seule.

Syntaxe

unite(data, col, conc ,sep= "", remove = TRUE)
arguments:
-data: The data frame used to reshape the dataset 
-col: Name of the new column
-conc: Name of the columns to concatenate
-sep: Indicates the symbol used that unites the variable, i.e:  "-", "_", "&"
-remove: Remove the old columns. By default, sets to TRUE

Exemple

Dans l'exemple ci-dessus, nous avons séparé le trimestre de l'année. Que faire si nous voulons les fusionner ? Nous utilisons le code suivant :

unit_tidier <- separate_tidier %>%
  unite(Quarter, Qrt, year, sep ="_")
head(unit_tidier)

Sortie :

##   country Quarter growth
## 1       A q1_2017   0.03
## 2       B q1_2017   0.05
## 3       C q1_2017   0.01
## 4       A q2_2017   0.05
## 5       B q2_2017   0.07
## 6       C q2_2017   0.02

Le cadre de données restructuré est maintenant prêt pour les étapes de modélisation décrites dans la suite du document. série de tutoriels R.

FAQ

La fonction `merge()` exprime chaque jointure à l'aide des options `all`, `all.x` et `all.y`, tandis que dplyr spécifie le comportement directement dans le verbe. dplyr préserve également l'ordre initial des lignes et renvoie un tibble. La méthode de base en R est décrite dans la documentation. fusionner les cadres de données guider.

Il s'agit de jointures de filtrage, qui n'ajoutent donc jamais de colonnes. `semi_join(x, y)` conserve les lignes de `x` ayant une correspondance dans `y`, et `anti_join(x, y)` conserve les lignes n'ayant pas de correspondance. Ces deux fonctions sont utiles pour vérifier les clés avant une jointure avec modification.

Associez-les explicitement avec `by = c("ID" = "customer_id")`, ou utilisez la fonction d'assistance plus récente `join_by(ID == customer_id)`. Sans mappage,ping, dplyr effectue des correspondances sur chaque nom de colonne partagée, ce qui peut silencieusement restreindre le résultat ou l'amplifier considérablement.

Une même clé peut se répéter des deux côtés, générant ainsi toutes les combinaisons possibles. Commencez par vérifier l'absence de duplication de chaque clé, puis agrégez les occurrences du côté « plusieurs », ou spécifiez l'intention de relation en passant l'argument `relationship = "many-to-many"`. dplyr signale les correspondances inattendues de type « plusieurs-à-plusieurs ».

filter() sélectionne les lignes, select() sélectionne les colonnes, arrange() trieLa fonction `mutate()` ajoute des colonnes, et `summarise()` fusionne les groupes créés par `group_by()`. L'opérateur `pipe` transmet un résultat au verbe suivant ; `%>%` est fourni avec dplyr et `|>` est une fonction native de R.

Les assistants IA peuvent profiler un cadre de données, signaler les clés dupliquées ou mal saisies avant une jointure et suggérer le reshaping.ping Utilisez un verbe adapté à la mise en page et expliquez clairement tout changement soudain du nombre de lignes. Relancez systématiquement le code et vérifiez vous-même les dimensions.

Oui. Copilote GitHub Fonctionne avec RStudio Desktop 2023.09.0 et versions ultérieures et complète les pipelines de jointure et de pivot à partir d'un commentaire. Notez que les suggestions ne sont pas déterministes ; vérifiez donc chaque ligne générée avant de l'exécuter.

Enchaînez les jointures ou réduisez une liste avec `Reduce(function(x, y) left_join(x, y, by = "ID"), list(df1, df2, df3))`. `purrr::reduce()` fait la même chose. Vérifiez `nrow()` après chaque étape, car les clés dupliquées s'accumulent lors des jointures.

Résumez cet article avec :