6.5 Traitements multi-tableaux

Dans vos analyses, vous serez confronté à devoir gérer plusieurs tableaux que vous allez vouloir rassembler en un seul. Selon le travail à réaliser, il s’agit de coller les tableaux l’un au-dessus de l’autre, l’un à côté de l’autre, ou d’effectuer un travail de fusion plus complexe. Nous allons maintenant voir ces différents cas successivement.

L’aide-mémoire Data Transformation with dplyr vous rappelle les différentes fonctions à utiliser dans sa section Combine Tables. Leur utilisation est également décrite en détails dans R for Data Science (2e).

6.5.1 Empilement vers le bas

Pour empiler des tableaux l’un au-dessus de l’autre, la fonction la plus simple est bind_rows() (tidy) ou sbind_rows() (speedy). Partons de données mesurées dans des mésoscosmes récifaux. Les différentes variables mesurées sont les suivantes :

  • les données physico-chimiques : la température, le pH, la salinité, l’oxygène dissous à l’aide, respectivement, d’un pH-mètre, d’un conductimètre et d’un oxymètre
  • la concentration en nutriments : orthophosphates (PO43-) et nitrates (NO3-) dissous dans l’eau par analyse colorimétrique

Pour la première série de mesures, des étudiants ont encodé deux tableaux qu’ils devront par la suite rassembler en un seul. Voici le premier tableau :

physico1 <- dtx(
  sample      = c("A0", "B0", "A0", "B0", "A0", "B0", "A0", "B0"),
  student     = c("st1", "st1", "st2", "st2", "st3", "st3", "st4", "st4"),
  ph          = c(7.94, 7.94, 7.94, 7.99, 7.94, 7.99, 7.94, 7.99),
  salinity    = c(34.0, 35.3, 33.9, 35.1, 34.0, 35.2, 33.9, 35.1),
  oxygen      = c(7.98, 8.00, 7.98, 7.98, 7.99, 7.86, 7.89, 7.98),
  temperature = c(24.6, 24.4, 25.1, 24.7, 24.9, 24.7, 25.0, 24.6))
rmarkdown::paged_table(physico1)

Voici le second tableau :

physico2 <- dtx(
  sample      = c("A0", "B0", "A0", "B0"),
  student     = c( "st5", "st5", "st6", "st6"),
  ph          = c(7.94, 7.99, 7.93, 7.99),
  salinity    = c(33.8, 35.0, 33.9, 35.1),
  oxygen      = c(7.96, 8.01, 7.90, 8.00),
  temperature = c(25.0, 24.6, 24.0, 24.0))
rmarkdown::paged_table(physico2)

L’empilement des deux tableaux de données en un seul se fait via la fonction tidy bind_rows() ou la fonction speedy sbind_rows() lorsque les tableaux contiennent les mêmes variables présentées exactement dans le même ordre comme ici :

physico <- sbind_rows(physico1, physico2)
rmarkdown::paged_table(physico)

6.5.2 Empilement à droite

Pour combiner des tableaux de données par les colonnes, de gauche à droite, la fonction la plus simple à utiliser est la fonction tidy bind_cols() ou la fonction speedy sbind_cols(). Les étudiants ont également réalisé des prélèvements d’eau qui ont été dosés par colorimétrie avec un analyseur automatique. Les échantillons des deux groupes ont été mesurés dans la même série par l’appareil, ce qui donne le tableau suivant pour les nutriments :

nutrients <- dtx(
  sample  = rep(c("A0", "B0"), times = 6),
  student = rep(c("st4", "st6", "st5", "st2", "st1", "st3"), each = 2),
  po4     = c(2.445, 0.374, 2.446, 0.394, 2.433, 0.361,
              2.441, 0.372, 2.438, 0.388, 2.445, 0.390),
  no3     = c(1.145, 0.104, 0.447, 0.066, 0.439, 0.093,
              0.477, 0.167, 0.443, 0.593, 0.450, 0.125))
rmarkdown::paged_table(nutrients)

Vous devez être très vigilant lors de l’utilisation de, bind_cols() ou sbind_cols() car ces fonctions combinent vos tableaux sans s’assurer que vos lignes soient alignées convenablement !

oceano %<-% bind_cols(nutrients, physico)
# New names:
# • `sample` -> `sample...1`
# • `student` -> `student...2`
# • `sample` -> `sample...5`
# • `student` -> `student...6`
rmarkdown::paged_table(oceano)

Qu’observez-vous ?

Effectivement nos deux tableaux de données n’ont pas les lignes dans le même ordre. Il faut être vigilant lors de ce genre de combinaison de tableaux. Il est préférable d’employer des fonctions de fusion de tableaux plus complexes comme full_join()/sfull_join() (ci-dessous). Pour utiliser correctement bind_cols() ou sbind_cols(), il faut vous assurer que les lignes des deux tableaux correspondent exactement, par exemple, en utilisant la fonction arrange() ou sarrange() :

nutrients2 %<-% arrange(nutrients, student, sample)
rmarkdown::paged_table(nutrients2)

Le tableau nutrients2 a maintenant les données présentées dans le même ordre (en lignes) que le tableau physico. Nous pouvons donc rassembler ces deux tableaux à l’aide de bind_cols() :

oceano %<-% bind_cols(nutrients2, physico)
# New names:
# • `sample` -> `sample...1`
# • `student` -> `student...2`
# • `sample` -> `sample...5`
# • `student` -> `student...6`
rmarkdown::paged_table(oceano)

Après vérification de l’adéquation des lignes, nous n’aurons plus besoin des colonnes sample...1 et student...2. La vérification automatique à l’aide de code R et l’élimination de ces variables du tableau oceano vous sont laissées comme exercices…

6.5.3 Fusion de tableaux

La fusion fera intervenir une ou plusieurs colonnes communes des deux tableaux pour déterminer quelles lignes du premier correspondent aux lignes du second. Ainsi, la fusion des tableaux est assurée d’être réalisée correctement, quel que soit l’ordre des lignes dans les deux tableaux d’origine. Utilisons la fonction speedy sfull_join() en joignant les lignes en fonction des valeurs de student et sample :

oceano <- sfull_join(nutrients, physico, by = c("student", "sample"))
rmarkdown::paged_table(oceano)

Observez bien ce dernier tableau. L’ordre retenu est celui de nutrients (le premier), mais les données issues de physico ont été retriées avant d’être fusionnées pour que les données correspondent. Comparez au tableau physico d’origine réimprimé ci-dessous :

rmarkdown::paged_table(physico)

Il existe, en fait, plusieurs versions pour la fusion de tableaux, représentées par une série de fonctions tidy XXX_join() ou speedy sXXX_join(). Lorsque les lignes entre les deux tableaux fusionnés correspondent parfaitement comme dans l’exemple traité ici, les différentes variantes ont le même effet. Mais lorsque des lignes diffèrent, les variantes ont leur importance :

  • (s)full_join() garde toutes les lignes,
full_join() par gadenbuie.
full_join() par gadenbuie.
  • (s)left_join() ne garde que les lignes uniques du tableau de gauche en plus des lignes communes,
left_join() par gadenbuie.
left_join() par gadenbuie.
  • (s)right_join() ne garde que les lignes uniques du tableau de droite en plus des lignes communes,
right_join() par gadenbuie.
right_join() par gadenbuie.
  • (s)inner_join() garde uniquement les lignes communes aux deux tableaux,
inner_join() par gadenbuie.
inner_join() par gadenbuie.
À vous de jouer !

Effectuez maintenant les exercices du tutoriel A06Lb_multi_table (Traitements multi-tableaux).

BioDataScience1::run("A06Lb_multi_table")

Réalisez le travail A06Ia_belgium_demo.

Travail individuel pour les étudiants inscrits au cours de Science des Données Biologiques I : visualisation à l’UMONS à terminer avant le 2022-12-12 16:00:00.

Initiez votre projet GitHub Classroom

Voyez les explications dans le fichier README.md.

Pour en savoir plus
  • Un aide-mémoire général en science des données avec lien vers les sites Web importants et les autres aide-mémoires. À partir de là, vous pouvez retrouver les packages, puis les fonctions qui réalisent telle ou telle transformation des données. Allez ensuite voir la page d’aide de la fonction avec ?ma_fonction. Vous pouvez aussi rechercher sur https://stackoverflow.com, en précédent le nom de la fonction par “[R]” (R entre crochets) pour restreindre la recherche uniquement dans les pages relatives au langage R.

  • Le chapitre relatif aux jointures de R for Data Science (2e) contient divers exemples de transformation des données à partir de un ou plusieurs tableaux et présente aussi d’autres formes de jointures.