Vous connaissez les opérations de pivot de base des jeux de données du format long au format large et vice versa. Cependant, comme c’est souvent le cas, les manipulations de base ne sont pas suffisantes pour le traitement des données que vous devez faire. Voyons maintenant le niveau suivant. Allons-y !
Maîtriser le pivot complexe du format large au format long et du format long au format large
Savoir utiliser les séparateurs comme outil de pivot
Nous présenterons ces jeux de données au fur et à mesure, mais voici un aperçu :
Données d’enquête d’une étude menée en Inde sur les dépenses des patients pour le traitement de la tuberculose
Données d’une étude sur les biomarqueurs des entéropathogènes en Zambie
Une enquête alimentaire au Vietnam
Parfois, vous avez plusieurs types de données au format large dans le même jeu de données. Considérez cet exemple factice de la taille et du poids des enfants sur deux ans :
enfant_stats <-
tibble::tribble(
~enfant, ~annee1_taille, ~annee2_taille, ~annee1_poids, ~annee2_poids,
"A", "80cm", "85cm", "5kg", "10kg",
"B", "85cm", "90cm", "7kg", "12kg",
"C", "90cm", "100cm", "6kg", "14kg"
)
enfant_statsSi vous pivotez toutes les colonnes des mesures, vous obtiendrez des données trop longues :
Ce n’est (généralement) pas ce que nous recherchons, car maintenant vous avez deux données différentes dans la même colonne- le poids et la taille.
Pour obtenir le bon format, vous devez utiliser l’argument
names_sep et l’identifiant “.value” :
Maintenant, nous avons une ligne pour chaque combinaison enfant-période, un format long correct !
Ce que fait le code ci-dessus peut ne pas être clair, mais vous
devriez déjà pouvoir répondre à l’exercice ci-dessous en reproduisant la
syntaxe de l’exemple précédant. Après cet exercice , nous expliquerons
l’argument names_sep et l’identifiant “.value” plus en
détail.
Considérez cet autre ensemble de données factice :
adulte_stats <-
tibble::tribble(
~adulte, ~annee1_IMC, ~annee2_IMC, ~annee1_VIH, ~annee2_VIH,
"A", 25, 30, "Positive", "Positive",
"B", 34, 28, "Negative", "Positive",
"C", 19, 17, "Negative", "Negative"
)
adulte_statsPivotez les données en un format long pour obtenir la structure suivante :
| adulte | annee | IMC | VIH |
|---|---|---|---|
## Vous n'avez pas encore défini l'objet de réponse, `Q_adulte_long`.
## ᐅ1ᐊ 2 3 4 5 6
##
## INDICE.
##
## Utilisez la fonction `pivot_longer` du package `tidyverse`.
## - Spécifiez `cols = 2:5` pour sélectionner les colonnes à pivoter.
## - Utilisez `names_sep = "_"` et `names_to = c("year", ".value")` pour formater les noms.
##
##
## SOLUTION
##
## adulte_stats %>%
## pivot_longer(cols = 2:5,
## names_sep = "_",
## names_to = c("annee", ".value"))
L’exemple ci-dessus enfant_stats a des nombres stockés
en tant que caractères […]
Comme vous l’avez vu dans la leçon précédente, vous pouvez facilement
extraire les nombres à partir du jeux de données de sortie au format
long en utilisant la fonction parse_number() de readr :
names_sep et “.value”Maintenant, décomposons l’appel pivot_longer() que nous
avons vu ci-dessus :
Remarquez que les noms de colonnes dans le dataframe
enfant_stats d’origine (annee1_taille,
annee2_taille etc.) sont composés de trois parties :
la période référencée : par exemple “annee1”
un séparateur de soulignement, “_”;
et le type de valeur enregistrée “taille” ou “poids”
Nous pouvons faire un tableau avec ces parties :
| nom_colonne | periode | separateur | “.value” |
|---|---|---|---|
annee1_taille |
annee1 | _ | taille |
annee2_taille |
annee2 | _ | taille |
annee1_poids |
annee1 | _ | poids |
annee2_poids |
annee2 | _ | poids |
Sur la base de ce tableau, il devrait maintenant être plus facile de
comprendre les arguments names_sep et names_to
que nous avons fournis à pivot_longer() :
names_sep = "_" :C’est le séparateur entre l’indicateur de période (année) et les valeurs (taille et poids) enregistrées.
Si nous utilisons un séparateur différent, l’argument va aussi
changer. Par exemple, si le séparateur est un espace vide, ” “, vous
aurez names_sep = " ", comme on le voit dans l’exemple
ci-dessous :
enfant_stats_espace_sep <-
tibble::tribble(
~enfant, ~`ann1 taille`, ~`ann2 taille`, ~`ann1 poids`, ~`ann2 poids`,
"A", "80cm", "85cm", "5kg", "10kg",
"B", "85cm", "90cm", "7kg", "12kg",
"C", "90cm", "100cm", "6kg", "14kg"
)
enfant_stats_espace_sep %>%
pivot_longer(2:5,
names_sep = " ",
names_to = c("periode", ".value"))names_to = c("periode", ".value")Ensuite, l’argument names_to indique comment les données
doivent être restructurées. Nous avons passé un vecteur de deux chaînes
de caractères, “periode” et “.value” à cet argument. Voyons le rôle de
chaque élément :
La chaîne “periode” indique que nous voulons placer les données de chaque année (ou période) dans une ligne séparée. Notez qu’il n’y a rien de spécial dans le mot “periode” utilisé ici ; nous pourrions changer cela par n’importe quelle autre chaîne. Donc, au lieu de “periode”, vous auriez pu écrire “temps” ou “annee_de_mesure” ou autre chose :
Maintenant, le placeholder “.value” est un
indicateur spécial, qui indique à pivot_longer() de créer
une colonne séparée pour chaque valeur distincte qui apparaît après le
séparateur. Dans notre exemple, ces valeurs sont “taille” et
“poids”.
La chaîne “.value” ne peut pas être remplacée arbitrairement. Par exemple, ceci ne fonctionnera pas :
Autrement dit, le placeholder “.value” indique à
pivot_longer() que nous voulons séparer les valeurs
“taille” et “poids” dans deux colonnes séparées, car nous avons deux
types de valeurs après le séparateur “_” dans les noms de colonnes.
Cela signifie que si vous avez un jeu de données au format large avec trois types de valeurs, vous obtiendrez trois colonnes séparées, une pour chaque type de valeur. Par exemple, considérez le jeu de données fictif ci-dessous qui montre les enregistrements d’enfants, à deux moments, pour les variables suivantes :
enfant_stats_trois_valeurs <-
tibble::tribble(
~enfant, ~t1_age, ~t2_age, ~t1_graisse, ~t2_graisse, ~t1_imc, ~t2_imc,
"a", "5 mois", "8 mois", "13%", "15%", 14, 15,
"b", "7 mois", "9 mois", "15%", "17%", 16, 18
)
enfant_stats_trois_valeursIci, dans les noms de colonnes, il y a trois types de valeurs qui
apparaissent après le séparateur “_” : age,
graisse et imc; la chaîne “.value” indique à
pivot_longer() de créer une nouvelle colonne pour chaque
type de valeur :
Un pédiatre enregistre les informations suivantes pour un ensemble d’enfants sur deux ans :
le tout en centimètres.
Voici le tableau de sortie :
croissance_stats <-
tibble::tribble(
~enfant,~ann1_tete,~ann2_tete,~ann1_cou,~ann2_cou,~ann1_hanche,~ann2_hanche,
"a", 45, 48, 23, 24, 51, 52,
"b", 48, 50, 24, 26, 52, 52,
"c", 50, 52, 24, 27, 53, 54
)
croissance_statsPivotez les données en un format long pour obtenir la structure suivante :
| enfant | annee | tete | cou | hanche |
|---|---|---|---|---|
## Vous n'avez pas encore défini l'objet de réponse, `Q_croissance_stats_long`.
## 1 ᐅ2ᐊ 3 4 5 6
##
## INDICE.
##
## Utilisez la fonction `pivot_longer` du package `tidyverse`.
## - Spécifiez `cols = 2:7` pour sélectionner les colonnes à pivoter.
## - Utilisez `names_to = c("year", ".value")` et `names_sep = "_"` pour formater les noms.
##
Dans tous les exemples que nous avons utilisés jusqu’à présent, les noms de colonnes étaient construits de telle sorte que le type de valeur venait après le séparateur. Rappelez-vous notre tableau :
| nom_colonne | periode | separateur | “.value” |
|---|---|---|---|
annee1_taille |
annee1 | _ | taille |
annee2_taille |
annee2 | _ | taille |
annee1_poids |
annee1 | _ | poids |
annee2_poids |
annee2 | _ | poids |
Mais bien sûr, les noms de colonnes pourraient être construits différemment, avec les types de valeurs venant avant le séparateur, comme dans cet exemple :
enfant_stats2 <-
tibble::tribble(
~enfant, ~taille_annee1, ~taille_annee2, ~poids_annee1, ~poids_annee2,
"A", "80cm", "85cm", "5kg", "10kg",
"B", "85cm", "90cm", "7kg", "12kg",
"C", "90cm", "100cm", "6kg", "14kg"
)
enfant_stats2Ici, les types de valeurs (taille et poids) viennent avant le “_” séparateur.
Comment notre commande pivot_longer() peut-elle
s’adapter à cela ? C’est simple ! Il suffit d’inverser l’ordre du
vecteur donné à l’argument names_to :
Donc, au lieu de names_to = c("temps", ".value"), vous
aurez names_to = c(".value", "temps") :
Et voilà !
Considérez le jeu de données suivant de la Zambie sur les entéropathogènes et leurs biomarqueurs.
enteropathogenes_zambie_large<- read_csv(here("data/fr_enteropathogenes_zambie_large.csv"))
enteropathogenes_zambie_largeCe jeu de données se compose des colonnes suivantes :
LPS_1 et LPS_2 : niveau des lipopolysaccharides, mesuré par Pyrochrome LAL, en EU/mL
LBP_1 et LBP_2 : niveau des protéines de liaison au LPS, en pg/mL
IFABP_1 et IFAPB_2 : niveau des protéines de liaison aux acides gras de type intestinal, en pg/mL
Pivotez le jeu de données pour qu’il ressemble à la structure suivante :
| ID | numero_echantillon | LPS | LBP | IFABP |
|---|---|---|---|---|
## Vous n'avez pas encore défini l'objet de réponse, `Q_enteropathogenes_zambie_large`.
## 1 2 ᐅ3ᐊ 4 5 6
##
## INDICE.
##
## Utilisez la fonction `pivot_longer` du package `tidyverse` pour réaliser la pivotisation.
## - Spécifiez les arguments `names_to = c(".value", "numero_echantillon")` et `names_sep = "_"`.
##
Jusqu’à présent, nous avons utilisé des ensembles de données personne-période (séries temporelles) pour illustrer l’idée de pivots complexes avec plusieurs types de valeurs.
Mais comme nous l’avons mentionné, tous les jeux de données nécessitant une restructuration ne sont pas forcément des données de séries temporelles. Voyons un exemple rapide qui n’est pas une série temporelle.
Vous pourriez mesurer la taille (cm) et le poids (kg) d’une série de couples parentaux dans un tableau comme celui-ci :
famille_stats <-
tibble::tribble(
~couple, ~pere_taille, ~pere_poids, ~mere_taille, ~mere_poids,
"a", 180, 80, 160, 70,
"b", 185, 90, 150, 76,
"c", 182, 93, 143, 78
)
famille_statsIci, nous avons deux types de valeurs différents (poids et taille) pour chaque personne du couple.
Pour pivoter à une ligne par personne, nous aurons encore besoin des
arguments names_sep et names_to :
Le séparateur est un trait de soulignement, “_”, donc nous avons
utilisé names_sep = "_" et comme les types de valeurs
viennent après le séparateur, l’identifiant “.value” a été placé en
deuxième dans l’argument names_to.
Un cas spécial que vous pourriez rencontrer est un ensemble de données où le séparateur est un point.
enfant_stats_point_sep <-
tibble::tribble(
~enfant, ~annee1.taille, ~annee2.taille, ~annee1.poids, ~annee2.poids,
"A", "80cm", "85cm", "5kg", "10kg",
"B", "85cm", "90cm", "7kg", "12kg",
"C", "90cm", "100cm", "6kg", "14kg"
)
enfant_stats_point_sep %>%
pivot_longer(2:5,
names_to = c("periode", ".value"),
names_sep = "\\.")Ici, nous avons utilisé la chaîne “\.” pour indiquer un point “.” parce que le “.” est un caractère spécial dans R qui dans certains cas doit être échappé.
Considérez à nouveau les données adulte_stats que vous avez vues ci-dessus. Maintenant, les noms des colonnes ont été légèrement modifiés.
adulte_stats_point_sep <-
tibble::tribble(
~adulte, ~`IMC.annee1`, ~`IMC.annee2`, ~`VIH.annee1`, ~`VIH.annee2`,
"A", 25, 30, "Positive", "Positive",
"B", 34, 28, "Negative", "Positive",
"C", 19, 17, "Negative", "Negative"
)
adulte_stats_point_sepEncore une fois, pivotez les données en un format long pour obtenir la structure suivante :
| adulte | annee | IMC | VIH |
|---|---|---|---|
## Vous n'avez pas encore défini l'objet de réponse, `Q_adulte2_long`.
## 1 2 3 ᐅ4ᐊ 5 6
##
## INDICE.
##
## Utilisez la fonction `pivot_longer` du package `tidyverse`.
## - Spécifiez `cols = 2:5` pour sélectionner les colonnes à pivoter.
## - N’oubliez pas d’échapper correctement le caractère point en utilisant `names_sep = "\."`
## et utilisez `names_to = c(".value", "year")` pour formater les noms.
##
Nous venons de voir comment effectuer certaines opérations complexes du format large au format long, qui, comme nous l’avons vu dans la leçon précédente, sont essentielles pour tracer et manipuler les données. Passons maintenant à la transformation inverse.
Il peut être utile de passer du format long au format large pour transformer et filtrer les données ou encore pour traiter des valeurs manquantes (NA). Dans ce format, vos mesures / données collectées deviennent les colonnes du jeu de données.
Cette fois-ci, nous allons utiliser le jeux de données originel sur les entéropathogènes en Zambie. En effet, ce que vous manipuliez jusqu’à présent était un jeu de données préparé pour vous, en format large. Le jeu de données originel est au format long et nous allons maintenant voir la préparation des données que j’ai faite au préalable, en coulisses. Vous êtes presque en train de devenir l’enseignant de cette leçon ;)
enteropathogenes_zambie_long <- read_csv(here("data/fr_enteropathogenes_zambie_long.csv"))
enteropathogenes_zambie_longVoici comment nous le convertissons du format long au format large :
enteropathogenes_zambie_large <-
enteropathogenes_zambie_long %>%
pivot_wider(
names_from = group,
values_from = c(LPS, LBP, IFABP)
)
enteropathogenes_zambie_largeVous pouvez voir que les valeurs de la variable group (1
ou 2) sont ajoutées aux noms des valeurs (LPS, LBP, IFABP) pour créer
les nouvelles colonnes représentant différents groupes de données : par
exemple, LPS_1 et LPS_2.
Nous considérons que c’est une option “avancée” du pivot car nous
pivotons plusieurs variables en même temps, mais comme vous pouvez le
voir, la syntaxe est assez simple. Nous utilisons les mêmes arguments
names_from et values_from qu’avec les pivots
plus simples que nous avons vus dans la leçon précédente.
Voyons un autre exemple, en utilisant les données de l’enquête alimentaire du Vietnam que vous avez manipulées précédemment :
diversite_alimentaire_vietnam_long <- read_csv(here("data/fr_diet_diversity_vietnam_long.csv"))
diversite_alimentaire_vietnam_longIci, nous allons utiliser la variable numero_visite pour
créer une nouvelle variable pour les différents apports enregistrés lors
des deux visites :
diversite_alimentaire_vietnam_large <-
diversite_alimentaire_vietnam_long %>%
pivot_wider(
names_from = numero_visite,
values_from = c(enerc_kcal_s, sec_s, eau_s, graisse_s)
)
diversite_alimentaire_vietnam_largeVous pouvez voir que les valeurs de la variable
numero_visite (1 ou 2) sont ajoutées aux noms des valeurs
(enerc_kcal_s, sec_s, graisse_s,
eau_s) pour créer les nouvelles colonnes représentant
différents groupes de données : par exemple, eau_s_1 et
eau_s_2. Nous avons pivoté en format large toutes ces
variables en même temps. Maintenant, chaque mesure de l’apport par
visite est représentée comme une seule variable (c’est-à-dire une
colonne) dans le jeu de données.
Avec ce format, il est facile de faire la somme de l’apport énergétique par ménage par exemple :
diversite_alimentaire_vietnam_large %>%
select(menage_id, enerc_kcal_s_1, enerc_kcal_s_2) %>%
mutate(energie_totale_kcal = enerc_kcal_s_1 + enerc_kcal_s_2) %>%
arrange(menage_id)Cependant, vous pourriez obtenir un résultat similaire avec le format long :
diversite_alimentaire_vietnam_long %>%
group_by(menage_id) %>%
summarize(energie_totale = sum(enerc_kcal_s)) Prenez le jeu de données tb_visites_long que nous avons
manipulé plus haut et pivotez-le à nouveau au format large.
Q_tb_visites_large <-
tb_visites_long %>%
pivot_wider(names_from = numero_visite,
values_from = c(visite_emplacement, visite_cout))## Correct !
## 1 2 3 4 5 ᐅ6ᐊ
##
## INDICE.
##
## Commencez par utiliser la fonction `pivot_wider` du package `tidyverse` sur le jeu de données `tb_visites_long`.
## Vous voudrez spécifier quelles colonnes fourniront les nouveaux noms de colonnes (`names_from`) et de quelles colonnes obtenir les valeurs (`values_from`).
## Ensuite, utilisez la fonction `rename` pour changer les noms de colonnes comme requis.
##
## tb_visites_long %>%
## pivot_wider(_________)
##
Vos compétences en manipulation de données viennent d’être renforcées avec le pivot avancé. Cette compétence s’avérera souvent essentielle lors de la manipulation des données du monde réel. Je ne doute pas que vous la mettrez bientôt en pratique. Elle est également essentielle, comme nous l’avons vu, pour la conception des graphiques. J’espère donc que le pivot vous sera utile non seulement pour votre manipulation de données, mais aussi pour pour la conception des graphiques.
Les membres suivants de l’équipe ont contribué à cette leçon :