7 votes

Ajouter la ligne de base/le grand total avec group_by() dans dplyr

Lorsque j'ai regroupé mes données par certains attributs, je veux ajouter une ligne "grand total" qui donne une base de comparaison. Regroupons mtcars par cylindres et carburateurs, par exemple :

by_cyl_carb <- mtcars %>%
  group_by(cyl, carb) %>%
  summarize(median_mpg = median(mpg),
        avg_mpg = mean(mpg),
        count = n())

...donne ces résultats :

> by_cyl_carb
# A tibble: 9 x 5
# Groups:   cyl [?]
    cyl  carb median_mpg avg_mpg count
   <dbl> <dbl>      <dbl>   <dbl> <int>
1     4     1       27.3    27.6     5
2     4     2       25.2    25.9     6
3     6     1       19.8    19.8     2
4     6     4       20.1    19.8     4
5     6     6       19.7    19.7     1
6     8     2       17.1    17.2     4
7     8     3       16.4    16.3     3
8     8     4       13.8    13.2     6
9     8     8       15      15       1

Quel est le code dont j'ai besoin pour qu'il fournisse une ligne de base ou un grand total qui ferait la somme (ou la moyenne ou la médiane) de toutes les données ? Les données souhaitées seraient quelque chose comme ceci :

    cyl  carb median_mpg avg_mpg count
   <chr> <chr>      <dbl>   <dbl> <int>
1     4     1       27.3    27.6     5
2     4     2       25.2    25.9     6
3     6     1       19.8    19.8     2
4     6     4       20.1    19.8     4
5     6     6       19.7    19.7     1
6     8     2       17.1    17.2     4
7     8     3       16.4    16.3     3
8     8     4       13.8    13.2     6
9     8     8       15      15       1
10   ttl   ttl      19.2    20.1    32

Il serait possible de manipuler la sortie de manière à ce que les données sous-groupées soient enroulées. Par exemple :

11   ttl    1       13.8    13.2     6
12   ttl    2       15      15       1
13   ttl    3       19.3    20.4    32
14 ... etc ...

L'exemple concret pour lequel je l'utilise est le prix de vente médian des maisons par région géographique et par année. Je veux donc établir un rapport sur le prix de vente médian pour chaque année géographique qui m'intéresse, mais je veux une comparaison de base pour chaque année indépendamment de la géographie.

Edit : Résolu avec deux solutions

@camille référencée ce lien qui a résolu le problème, ainsi que @MKR qui a proposé une solution. Voici un code qui pourrait fonctionner :

by_cyl_carb <- mtcars %>%
  mutate_at(vars(c(cyl,carb)), funs(as.character(.))) %>%
  bind_rows(mutate(., cyl = "All cylinders")) %>%
  bind_rows(mutate(., carb = "All carburetors")) %>%
  group_by(cyl, carb) %>%
  summarize(median_mpg = median(mpg),
            avg_mpg = mean(mpg),
            count = n())

> by_cyl_carb
# A tibble: 19 x 5
# Groups:   cyl [?]
   cyl           carb            median_mpg avg_mpg count
   <chr>         <chr>                <dbl>   <dbl> <int>
 1 4             1                     27.3    27.6     5
 2 4             2                     25.2    25.9     6
 3 4             All carburetors       26      26.7    11
 4 6             1                     19.8    19.8     2
 5 6             4                     20.1    19.8     4
 6 6             6                     19.7    19.7     1
 7 6             All carburetors       19.7    19.7     7
 8 8             2                     17.1    17.2     4
 9 8             3                     16.4    16.3     3
10 8             4                     13.8    13.2     6
11 8             8                     15      15       1
12 8             All carburetors       15.2    15.1    14
13 All cylinders 1                     22.8    25.3     7
14 All cylinders 2                     22.1    22.4    10
15 All cylinders 3                     16.4    16.3     3
16 All cylinders 4                     15.2    15.8    10
17 All cylinders 6                     19.7    19.7     1
18 All cylinders 8                     15      15       1
19 All cylinders All carburetors       19.2    20.1    32

8voto

MKR Points 16303

Une solution utilisant dplyr::bind_rows y mutate_at peut être réalisé comme suit :

library(tidyverse)
mtcars %>%
  group_by(cyl, carb) %>%
  summarize(median_mpg = median(mpg),
            avg_mpg = mean(mpg),
            count = n()) %>% 
  ungroup() %>%
  mutate_at(vars(cyl:carb), funs(as.character(.))) %>%
  bind_rows(summarise(cyl = "ttl", carb = "ttl", mtcars, median_mpg = median(mpg),
                      avg_mpg = mean(mpg),
                      count = n()))

# # A tibble: 10 x 5
#   cyl   carb  median_mpg avg_mpg count
#   <chr> <chr>      <dbl>   <dbl> <int>
# 1 4     1           27.3    27.6     5
# 2 4     2           25.2    25.9     6
# 3 6     1           19.8    19.8     2
# 4 6     4           20.1    19.8     4
# 5 6     6           19.7    19.7     1
# 6 8     2           17.1    17.2     4
# 7 8     3           16.4    16.3     3
# 8 8     4           13.8    13.2     6
# 9 8     8           15.0    15.0     1
#10 ttl   ttl         19.2    20.1    32

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X