6.5 Traitements multi-tableaux

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

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(). Partons de données mesurées dans des mésoscosmes récifaux lors des travaux pratiques du cours d’océanographie générale. 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 pHmè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, ils ont encodé deux fichiers qu’ils ont du par la suite rassembler. Le groupe 1 a encodé le tableau suivant :

physico1 <- as_dataframe(tibble(
  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)

Le groupe 2 a encodé ce tableau :

physico2 <- as_dataframe(tibble(
  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 bind_rows() lorsque les tableaux contiennent les mêmes variables présentées exactement dans le même ordre comme ici :

physico <- bind_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 bind_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 <- as_dataframe(tibble(
  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() car cette dernière combine 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_joint() (ci-dessous). Pour utiliser correctement bind_cols(), il faut vous assurer que les lignes des deux tableaux correspondent exactement, par exemple, en utilisant arrange() :

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 sample1 et student1. 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 full_join() en joignant les lignes en fonction des valeurs de student et sample :

oceano <- full_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 xxx_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 :

  • full_join() garde toutes les lignes,
full_join() par gadenbuie.
full_join() par gadenbuie.
  • 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.
  • 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.
  • 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_tableau (Traitements multi-tableaux).

BioDataScience1::run("A06Lb_multi_tableau")

Note : le projet GitHub Classroom ci-dessous est à réaliser par groupes de quatre étudiants. Il requiert d’avoir assimilé l’ensemble de la matière des six premiers modules du cours.

Réalisez en groupe le travail A06Ga_belgium_demo.

Travail en groupe de 4 pour les étudiants inscrits au cours de Science des Données Biologiques I : visualisation à l’UMONS à terminer avant le 2021-12-24 23:59:59.

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 données cas par variables (tidy data) de R for Data Science contient divers exemples et exercices supplémentaires de transformation des données à partir de un ou plusieurs tableaux.