首页 > 解决方案 > 在 dplyr 中使用 group_by() 添加基线/总计

问题描述

当我按某些属性对数据进行分组时,我想添加一个“总计”行来提供比较基线。让我们按气缸和化油器对 mtcar 进行分组,例如:

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

...产生这些结果:

> 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

我需要什么代码才能提供一个基线或总计,以对所有数据求和(或平均值或中位数)?所需的数据将是这样的:

    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

对此的一个扭曲将能够操纵输出,以便将分组的数据汇总。例如:

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

我使用这个的现实生活中的例子是按年按地理位置划分的房屋销售价格中位数。因此,我想报告我感兴趣的每个地理年份的中位销售价格,但我希望无论地理位置如何,都需要对每一年进行基线比较。

编辑:用两种解决方案解决

@camille 引用了这个链接,它解决了这个问题,@MKR 也提供了一个解决方案。这是一个可能有效的代码:

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

标签: rgroup-bydplyr

解决方案


使用dplyr::bind_rows和的解决方案mutate_at可以实现为:

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

推荐阅读