La manipulation de données implique souvent d’appliquer les mêmes
opérations séparément à différents groupes au sein des données. Ce
motif, parfois appelé “split-apply-combine”, est facilement réalisable
dans {dplyr} en enchaînant le verbe group_by() avec
d’autres verbes de manipulation tels que filter(),
mutate() et arrange() (que vous avez déjà vus
!).
Dans cette leçon, vous deviendrez confiant avec ce type de manipulations groupées.
Commençons.
group_by() avec
arrange(), filter() et mutate()
pour effectuer des opérations groupées sur un jeu de données.Cette leçon exigera la suite de packages {tidyverse} et le package {here} :
Dans cette leçon, nous utiliserons encore les données de l’enquête
sérologique COVID-19 menée à Yaoundé, au Cameroun. Ci-dessous, nous
importons les données, créons un petit sous-ensemble du jeu de données,
yao et un sous-ensemble encore plus petit,
yao_sexe_poids.
yao <-
read_csv(here::here('data/fr_yaounde_data.csv')) %>%
select(sexe, age, cat_age, poids_kg, occupation, resultat_igg, resultat_igm)
yaoPour les questions pratiques, nous utiliserons également le jeu de données sur la sarcopénie que vous avez déjà vu :
La fonction arrange() ordonne les lignes d’un jeu de
données par les valeurs des colonnes sélectionnées. Cette fonction est
sensible aux groupements uniquement lorsque nous définissons son
argument .by_group à TRUE. Pour illustrer
cela, considérons le jeu de données yao_sexe_poids :
Nous pouvons organiser ce jeu de données par poids de cette façon :
Comme prévu, les poids les plus faibles ont été placés en haut de la trame de données.
Si nous regroupons d’abord les données, nous pourrions nous attendre à un résultat différent :
Mais comme vous le voyez, l’organisation est toujours la même.
Ce n’est que lorsque nous définissons l’argument
.by_group à TRUE que nous obtenons quelque
chose de différent :
Maintenant, les données sont d’abord triées par sexe (toutes les femmes en premier), puis par poids.
arrange() peut regrouper
automatiquementEn réalité, nous n’avons pas besoin de group_by() pour
organiser par groupe ; nous pouvons simplement mettre plusieurs
variables dans la fonction arrange() pour obtenir le même
effet.
Ainsi, cette simple commande arrange() :
est équivalente à la commande plus complexe group_by(),
arrange() utilisée précédemment :
La commande arrange(sexe, poids_kg) dit à R d’organiser
les lignes d’abord par sexe, puis par poids.
Évidemment, cette syntaxe, avec juste arrange(), et pas
de group_by() est plus simple, donc vous pouvez vous y
tenir.
Rappel
desc() pour l’ordre décroissant
Rappelez-vous que pour classer en ordre décroissant, nous
pouvons mettre la variable cible dans desc(). Donc, par
exemple, pour trier par sexe et poids, mais avec les personnes les plus
lourdes en haut, nous pouvons exécuter :
Avec une commande arrange(), triez les données
sarcopenia d’abord par sexe, puis par force de préhension.
(Si c’est fait correctement, la première ligne devrait être celle d’une
femme avec une force de préhension de 1,3 kg). Pour rendre
l’organisation claire, vous devriez d’abord select() les
variables de sexe et de force de préhension.
Le jeu de données sarcopenia contient une colonne
groupe_d_age, qui stocke les groupes d’âge en chaîne de
caractères (les groupes d’âge sont “Sixties”, “Seventies” et
“Eighties”). Convertissez cette variable en un facteur avec les niveaux
dans le bon ordre (d’abord “Sixties”, puis “Seventies” et ainsi de
suite). (Astuce : Revenez sur la leçon case_when() si vous
ne voyez pas comment réattribuer un niveau à un facteur).
Ensuite, avec une commande imbriquée à arrange(),
classez les données d’abord par la variable facteur
groupe_d_age nouvellement créée (les individus les plus
jeunes en premier) puis par taille_metres, avec les
individus les plus petits en premier.
La fonction filter() conserve ou supprime des lignes en
fonction d’une condition. Si filter() est appliquée à des
données groupées, l’opération de filtrage est réalisée séparément pour
chaque groupe.
Pour illustrer cela, considérons à nouveau le jeu de données
yao_sexe_poids :
Si nous voulons filtrer les données pour la personne la plus lourde, nous pourrions exécuter :
Mais si nous voulons obtenir la personne la plus lourde par groupe de
sexe (l’homme le plus lourd et la femme la plus lourde), nous
pouvons utiliser group_by(sex) puis filter()
:
Parfait ! Le code ci-dessus peut être traduit par “Pour chaque groupe
de sexe, conserve la ligne avec la valeur maximale
poids_kg”.
La fonction filter() fonctionne bien avec un nombre
quelconque de groupements imbriqués.
Par exemple, si nous voulons voir l’homme le plus lourd et la femme
la plus lourde par groupe d’âge, nous pourrions exécuter le
code suivant sur le jeu de données yao :
Ce code regroupe par sexe et catégorie d’âge, puis trouve la personne la plus lourde dans chaque sous-catégorie.
(Pourquoi avons-nous 10 lignes dans la sortie ? Eh bien, 2 groupes de sexe x 5 groupes d’âge = 10 groupements uniques.)
La sortie est un peu dispersée, donc nous pouvons enchaîner cela avec
la fonction arrange(), pour organiser par sexe et groupe
d’âge.
Maintenant, les données sont plus faciles à lire. Toutes les femmes
viennent en premier, puis les hommes. Mais nous remarquons un
arrangement étrange des groupes d’âge ! Ceux âgés de 5 à 14 ans
devraient venir en premier dans l’arrangement. Bien sûr, nous
avons appris comment corriger cela avec la fonction
factor() et son argument levels :
yao %>%
mutate(cat_age = factor(
cat_age,
levels = c("5 - 14", "15 - 29", "30 - 44", "45 - 64", "65 +")
)) %>%
group_by(sexe, cat_age) %>%
filter(poids_kg == max(poids_kg)) %>%
arrange(sexe, cat_age)Maintenant, nous avons une sortie bien organisée !
mutate() est utilisé pour modifier les colonnes ou pour
en créer de nouvelles. Avec des données groupées, mutate()
opère sur chaque groupe indépendamment.
Considérons d’abord un appel régulier à mutate(), pas un
groupé. Imaginez que vous voulez ajouter une colonne qui classe les
répondants par poids. Cela peut être fait avec la fonction
rank() à l’intérieur d’un appel à mutate()
:
La sortie montre que la première ligne est le 901ème individu le plus
léger. Mais il serait plus intuitif de classer dans l’ordre décroissant
avec la personne la plus lourde en premier. Nous pouvons le faire avec
la fonction desc() :
La sortie montre que la personne de la première ligne est la 71ème personne la plus lourde.
Maintenant, essayons d’écrire un appel groupé à
mutate(). Imaginez que nous voulons ajouter cette colonne
de classement par poids par groupe de sexe dans le jeu de
données. Autrement dit, nous voulons connaître le classement de chaque
personne par poids dans leur catégorie de sexe. Dans ce cas, nous
pouvons combiner group_by(sex) avec mutate()
:
Nous voyons maintenant que la personne de la première ligne est la 53ème femme la plus lourde. (Le .5 indique que ce rang est à égalité avec quelqu’un d’autre dans les données.)
Nous pourrions également organiser les données pour rendre les choses plus claires :
yao_sexe_poids %>%
group_by(sexe) %>%
mutate(poids_ordre = rank(desc(poids_kg))) %>%
arrange(sexe, poids_ordre)Bien sûr, comme avec les autres verbes que nous avons vus,
mutate() fonctionne aussi avec des groupes imbriqués.
Par exemple, ci-dessous nous créons le groupe imbriqué d’âge
et de sexe avec le jeu de données yao, puis nous
ajoutons une colonne de rang avec mutate() :
La sortie montre que la personne de la première ligne est la 20ème femme la plus lourde dans le groupe d’âge de 45 à 64 ans.
Avec les données sarcopenia, groupez par
groupe_d_age, puis dans une nouvelle variable appelée
force_prehension_ordre, calculez le rang de la force de
préhension de chaque individu par groupe d’âge. (Pour calculer le rang,
utilisez mutate() et la fonction rank() avec
sa méthode par défaut pour les égalités.)
Attention
N’oubliez pas de dégrouper les données avant de procéder à une analyse plus approfondie
Comme il a été mentionné auparavant, il est important de dégrouper vos données avant de faire une analyse plus détaillée.
Considérez ce dernier exemple, où nous avons calculé le rang de poids des individus par groupe d’âge et de sexe :
Si, dans le processus d’analyse, vous avez stocké cette sortie comme un nouveau jeu de données :
Et puis, plus tard, vous avez repris le jeu de données et essayé une autre analyse, par exemple, en filtrant pour obtenir la personne la plus âgée dans les données :
Vous pourriez être confus par la sortie! Pourquoi y a-t-il 55 lignes de “personnes les plus âgées”?
Cela serait dû au fait que vous avez oublié de dégrouper les données avant de les stocker pour une analyse plus approfondie. Faisons cela correctement maintenant
yao_modifie <-
yao %>%
group_by(sexe, cat_age) %>%
mutate(poids_ordre = rank(desc(poids_kg)))%>%
ungroup()Maintenant, nous pouvons obtenir correctement la/les personne(s) la/les plus âgée(s) dans le jeu de données :
group_by() est un outil merveilleux pour arranger,
modifier, filtrer en fonction des groupes au sein d’une ou plusieurs
variables.
Il existe de nombreuses façons de combiner ces verbes pour manipuler vos données. Nous vous invitons à prendre un peu de temps pour essayer ces verbes dans différentes combinaisons !
À la prochaine !
Les membres de l’équipe suivants ont contribué à cette leçon :
Certains matériaux de cette leçon ont été adaptés des sources suivantes :
Horst, A. (2022). Dplyr-learnr. https://github.com/allisonhorst/dplyr-learnr (Travail original publié en 2020)
Grouper par une ou plusieurs variables. (n.d.). Consulté le 21 Février 2022, sur https://dplyr.tidyverse.org/reference/group_by.html
Créer, modifier et supprimer des colonnes — Mutate. (n.d.). Consulté le 21 Février 2022, sur https://dplyr.tidyverse.org/reference/mutate.html
Sélectionner des lignes en utilisant les valeurs des colonnes — Filter. (n.d.). Consulté le 21 Février 2022, sur https://dplyr.tidyverse.org/reference/filter.html
Arranger les lignes par valeurs de colonnes — Arrange. (n.d.). Consulté le 21 Février 2022, sur https://dplyr.tidyverse.org/reference/arrange.html
L’œuvre d’art a été adaptée de :