head(ToothGrowth, 4) len supp dose
1 4.2 VC 0.5
2 11.5 VC 0.5
3 7.3 VC 0.5
4 5.8 VC 0.5
Moyenne, écart-type et effectifs par groupe — une variable de groupe ou plusieurs, deux approches qui concordent
Résumez un data frame par groupe en R avec dplyr group_by() + summarise() (moyenne, écart-type, n, plusieurs statistiques, plusieurs variables de groupe, across() pour de nombreuses colonnes, l’argument .groups) et les approches base R aggregate(), tapply() et by() — les deux moteurs, le même résultat.
26 juin 2026
11 juillet 2026
df |> group_by(g) |> summarise(m = mean(x)) — groupez, puis réduisez chaque groupe à une seule ligne.aggregate(x ~ g, data = df, FUN = mean) fait la même chose avec une formule ; tapply() pour une statistique unique.summarise() : mean, sd et n() (l’effectif du groupe) ensemble.group_by() ou utilisez cbind(...) ~ g1 + g2 dans aggregate().« Quelle est la moyenne des ventes par région ? » « Combien de patients par bras de traitement, et la réponse moyenne dans chacun ? » Calculer une statistique par groupe — le motif grouper-puis-résumer — est la tâche d’analyse de données la plus courante qui soit.
Deux approches le font, et vous rencontrerez les deux :
group_by() + summarise() — divisez les données en groupes, réduisez chacun à une ligne de résumé ; cela se lit comme la phrase que vous diriez à voix haute.aggregate() / tapply() / by() — une interface par formule, aucun paquet requis, fonctionne partout.Cette leçon calcule une moyenne par groupe, plusieurs statistiques à la fois, des résumés sur plusieurs variables de groupe, et la même statistique sur de nombreuses colonnes. Les deux moteurs renvoient les mêmes nombres, vous pouvez donc lire n’importe quel code et choisir celui que vous préférez.
Nous utilisons le jeu de données intégré ToothGrowth — la longueur de croissance dentaire len pour des cobayes sous deux compléments (supp) à trois doses (dose).
group_by() + summarise()group_by() marque les lignes par groupe ; summarise() réduit ensuite chaque groupe à une seule ligne avec ce que vous calculez. Ici, la moyenne de len par complément :
# A tibble: 2 × 2
supp mean_len
<fct> <dbl>
1 OJ 20.7
2 VC 17.0
Une ligne par groupe, une colonne de résumé. Le résultat est un data frame ordinaire que vous pouvez tracer ou joindre.
aggregate()aggregate() utilise une formule : value ~ group, les données et la fonction à appliquer. Les mêmes deux groupes, les mêmes moyennes :
Les nombres correspondent exactement à summarise() — aggregate() est l’approche base R par formule, et c’est ce qu’utilise beaucoup de code ancien (et les tutoriels sthda).
À l’intérieur d’un seul summarise(), calculez autant de résumés que nécessaire. n() donne l’effectif du groupe ; combinez-le avec mean et sd pour le trio que vous rapportez le plus souvent :
aggregate() peut renvoyer plusieurs statistiques en écrivant une fonction qui retourne un vecteur nommé :
supp len.n len.mean len.sd
1 OJ 30.000000 20.663333 6.605561
2 VC 30.000000 16.963333 8.266029
La colonne len revient sous forme de matrice des trois statistiques — les mêmes n, mean et sd que le résultat dplyr, simplement disposés différemment. Pour une statistique unique, tapply(ToothGrowth$len, ToothGrowth$supp, mean) est l’outil base R le plus direct.
Listez chaque variable de groupe dans group_by(). Ici, une ligne par combinaison supp × dose :
# A tibble: 6 × 4
supp dose mean_len sd_len
<fct> <dbl> <dbl> <dbl>
1 OJ 0.5 13.2 4.46
2 OJ 1 22.7 3.91
3 OJ 2 26.1 2.66
4 VC 0.5 7.98 2.75
5 VC 1 16.8 2.52
6 VC 2 26.1 4.80
.groups = "drop" dégroupe le résultat pour que les étapes suivantes le traitent comme un data frame ordinaire (et fait taire le message de groupement — voir Problèmes courants).
Ajoutez les variables à droite de la formule avec + :
supp dose len
1 OJ 0.5 13.23
2 VC 0.5 7.98
3 OJ 1.0 22.70
4 VC 1.0 16.77
5 OJ 2.0 26.06
6 VC 2.0 26.14
Six lignes — chaque combinaison de complément et de dose — avec les mêmes moyennes de groupe que la version dplyr.
across()Lorsque vous voulez la même statistique sur plusieurs colonnes de valeurs, across() à l’intérieur de summarise() évite de vous répéter. Ici, la moyenne de chaque colonne numérique d’iris par espèce :
# A tibble: 3 × 5
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 3.43 1.46 0.246
2 versicolor 5.94 2.77 4.26 1.33
3 virginica 6.59 2.97 5.55 2.03
L’équivalent base R est aggregate() avec toutes les colonnes numériques à gauche via . ~ group :
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa 5.006 3.428 1.462 0.246
2 versicolor 5.936 2.770 4.260 1.326
3 virginica 6.588 2.974 5.552 2.026
Les deux renvoient une ligne par espèce avec les moyennes par colonne — across() est la forme concise de dplyr, . ~ group celle de base R.
Pour appliquer plusieurs fonctions sur ces colonnes en un seul appel, passez à across() une liste nommée de fonctions. Enveloppez chacune dans une courte fonction anonyme (\(x) …) afin de pouvoir régler ses arguments (comme na.rm = TRUE) directement — la forme moderne depuis dplyr 1.1.0. L’argument .names contrôle les noms de sortie à l’aide d’un modèle glue : {col} est la colonne source, {fn} le nom de la fonction dans la liste :
# A tibble: 3 × 9
Species Sepal.Length_mean Sepal.Length_sd Sepal.Width_mean Sepal.Width_sd
<fct> <dbl> <dbl> <dbl> <dbl>
1 setosa 5.01 0.352 3.43 0.379
2 versicolor 5.94 0.516 2.77 0.314
3 virginica 6.59 0.636 2.97 0.322
# ℹ 4 more variables: Petal.Length_mean <dbl>, Petal.Length_sd <dbl>,
# Petal.Width_mean <dbl>, Petal.Width_sd <dbl>
Chaque colonne numérique renvoie désormais une paire {col}_{fn} — Sepal.Length_mean, Sepal.Length_sd, et ainsi de suite — la moyenne et l’écart-type de chaque mesure par espèce en un seul appel. C’est l’idiome pour calculer plusieurs statistiques de résumé sur de nombreuses colonnes à la fois.
Les blocs ci-dessus se sont exécutés lors de la génération. Modifiez celui-ci et appuyez sur Run pour résumer vos propres groupes — il s’exécute dans votre navigateur via webR (sans installation).
Collez un head() de votre propre tableau et demandez à Prova « donne-moi la moyenne et l’effectif des ventes par région et par trimestre, et vérifie-le par rapport au nombre de lignes » — elle écrit l’appel group_by() |> summarise(). Comme le runtime est juste là, vous l’exécutez et vous recoupez les effectifs de groupe avec nrow(), ce qui vous fait confiance dans le résumé au lieu d’accepter une réponse plausible sur parole. The runtime is the judge. Demander à Prova →
Vous travaillez en Python ? Un guide pandas groupby().agg() arrive bientôt dans la série Python.
summarise() a affiché un message à propos de « grouped output » / .groups. Lorsque vous groupez par plusieurs variables, summarise() retire le dernier niveau de groupement et vous le signale. C’est inoffensif, mais pour le contrôler (et faire taire le message) définissez .groups = "drop" (un data frame dégroupé ordinaire), "keep" ou "drop_last". Ajouter .groups = "drop" est le choix habituel lorsque le résumé alimente une étape ultérieure.
Vous avez obtenu une seule ligne au lieu d’une par groupe. Vous avez appelé summarise() sans group_by() au préalable (ou le groupement avait déjà été retiré). summarise() réduit les groupes existants à ce moment-là — aucun groupe signifie que le tableau entier devient une seule ligne. Vérifiez que group_by() s’exécute juste avant.
aggregate(len ~ supp) a supprimé les lignes avec des NA. L’interface par formule d’aggregate() retire par défaut les lignes ayant des valeurs manquantes. Pour les conserver, passez na.action = na.pass et gérez les NA à l’intérieur de FUN (par ex. mean(x, na.rm = TRUE)). En dplyr, utilisez mean(x, na.rm = TRUE) directement dans summarise().
dplyr : df |> group_by(g) |> summarise(m = mean(x)). Base R : aggregate(x ~ g, data = df, FUN = mean), ou tapply(df$x, df$g, mean) pour une statistique unique rapide. Les trois donnent les mêmes moyennes par groupe.
Ils calculent les mêmes résumés par groupe. group_by() |> summarise() (dplyr) se lit clairement, s’enchaîne dans un pipeline et gère proprement de nombreuses statistiques et across(). aggregate() (base R) utilise une formule value ~ group, ne nécessite aucun paquet, et c’est ce qu’utilise la plupart du code ancien/sthda. Choisissez selon le code ; les nombres concordent.
En dplyr, utilisez n() à l’intérieur de summarise() : df |> group_by(g) |> summarise(n = n()), ou le raccourci count(df, g). En base R, table(df$g) compte les lignes par groupe, ou aggregate(x ~ g, df, length).
dplyr : listez-les dans group_by(g1, g2) — vous obtenez une ligne par combinaison. Base R : ajoutez-les à la formule avec + : aggregate(x ~ g1 + g2, data = df, FUN = mean). Les deux produisent une ligne pour chaque combinaison de groupes.
.groups dans summarise ?
Après un groupement par plusieurs variables, summarise() retire le dernier niveau de groupement et affiche une note. Elle est informative, pas une erreur. Définissez .groups = "drop" pour renvoyer un data frame dégroupé ordinaire (et faire taire le message), ou "keep" pour conserver tous les groupes.
À partir de ToothGrowth, calculez l’effectif, la moyenne et l’écart-type de len pour chaque dose. Utilisez dplyr group_by() + summarise().
x par groupe g ?
Dans le data frame df, lequel renvoie une moyenne par groupe ?
A. summarise(df, m = mean(x)) B. df |> group_by(g) |> summarise(m = mean(x)) C. mean(df$x, by = df$g)
Afficher la réponse
B. Vous devez faire group_by(g) avant summarise() pour que chaque groupe se réduise à sa propre ligne. A résume le tableau entier à une seule moyenne globale (sans groupement). C n’est pas valide — mean() n’a pas d’argument by ; l’approche base R est tapply(df$x, df$g, mean) ou aggregate(x ~ g, df, mean).
Résumer par groupe se ramène à deux outils équivalents : dplyr group_by() |> summarise() (avec n() pour les effectifs, plusieurs statistiques en un seul appel, et across() pour de nombreuses colonnes), ou base R aggregate(value ~ group, FUN = ...) (avec tapply() pour une statistique unique rapide). Les deux renvoient les mêmes nombres — utilisez dplyr pour des pipelines lisibles, base R quand vous voulez zéro dépendance. Définissez .groups = "drop" lorsque le résumé alimente une étape ultérieure.
Prouvez que vous savez le faire. Maîtrisez toute la série Manipulation de données en R et Python — suivez votre parcours, construisez des projets et obtenez un certificat.
Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.
dès 15 $/mois facturé annuellement
✓ Vous êtes Pro — continuez. The runtime is the judge.
Recevez les nouvelles leçons R & Python par e-mail
Pratique, reproductible, sans spam. Désinscription à tout moment.
Double opt-in. Nous ne partageons jamais votre e-mail.
Cette leçon est reproductible : chaque résultat de cette page a été produit par le code affiché — modifiez n’importe quel bloc et appuyez sur Run pour le reproduire dans votre navigateur. The runtime is the judge.
@online{2026,
author = {},
title = {Group By en R : résumé par groupe avec dplyr \& base R},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/programming/data-wrangling/summarize-by-group-in-r},
langid = {fr}
}