【问题标题】:How to summarise by group AND get a summary of the overall dataset using dplyr in R如何按组汇总并使用 R 中的 dplyr 获取整个数据集的摘要
【发布时间】:2019-11-11 05:10:57
【问题描述】:

我想计算不同组的摘要并同时计算整个(未分组)数据集的摘要,最好使用 dplyr(或非常适合 dplyr 管道的东西)。

可以通过分别计算组摘要,然后是整体摘要,然后将结果连接起来来达到预期的结果。然而,这似乎有点低效,我希望有一个更简单的解决方案,需要更少的代码重复。我在文档或其他问题中没有找到与此相关的任何内容。

可重现的数据:

library(tidyverse)
set.seed(500)
dat <- 
    data_frame(treatment = sample(c("Group1", "Group2", "Group3"), 100, replace = TRUE),
               recruitment_strategy = sample(c("Strategy 1", "Strategy 2", "Strategy 3", "Strategy 4", "Strategy 5"), 100, replace = TRUE),
               Variable_A = rnorm(100),
               Variable_B = rnorm(100),
               Variable_C = rnorm(100))

按组计算多个变量的均值和整个数据集的均值的代码:

count_by_group <- dat %>% 
    group_by(treatment) %>% 
    count(recruitment_strategy) %>%
    mutate(`n (%)` = paste0(n, " (", round(n / sum(n)*100,0), "%)")) %>%
    select(-n) %>%
    spread(treatment, `n (%)`)

count_overall <- dat %>% 
    count(recruitment_strategy) %>%
    mutate(`n (%)` = paste0(n, " (", round(n / sum(n)*100,0), "%)")) %>%
    select(-n) %>%
    rename(Overall_dataset = `n (%)`)

left_join(count_by_group, count_overall)

使用上面的代码实现了所需的输出:每个组的平均值表,旁边是整体平均值:

  variable   Group1  Group2  Group3 Overall_dataset
  <chr>       <dbl>   <dbl>   <dbl>           <dbl>
1 Variable_A -0.154  0.0385  0.263           0.0351
2 Variable_B  0.212 -0.232  -0.124          -0.0671
3 Variable_C -0.195  0.194   0.0508          0.0376

对分类变量进行类似处理,以获取每个组以及整个数据集的计数和百分比:

count_by_group <- dat %>% 
    group_by(treatment) %>% 
    count(recruitment_strategy) %>%
    mutate(`n (%)` = paste0(n, " (", round(n / sum(n)*100,0), "%)")) %>% # calculate percentage in the desired format for table
    select(-n) %>%
    spread(treatment, `n (%)`)

count_overall <- dat %>% 
    count(recruitment_strategy) %>%
    mutate(`n (%)` = paste0(n, " (", round(n / sum(n)*100,0), "%)")) %>% # calculate percentage in the desired format for table
    select(-n) %>%
    rename(Overall_dataset = `n (%)`)

left_join(count_by_group, count_overall)

  recruitment_strategy Group1  Group2   Group3  Overall_dataset
  <chr>                <chr>   <chr>    <chr>   <chr>          
1 Strategy 1           2 (6%)  13 (30%) 4 (16%) 19 (19%)       
2 Strategy 2           8 (26%) 6 (14%)  6 (24%) 20 (20%)       
3 Strategy 3           6 (19%) 12 (27%) 3 (12%) 21 (21%)       
4 Strategy 4           9 (29%) 4 (9%)   5 (20%) 18 (18%)       
5 Strategy 5           6 (19%) 9 (20%)  7 (28%) 22 (22%) 

是否有一种解决方案可以在一个步骤中获得分组摘要和总体摘要,而不是要求分配两个单独的对象,然后将它们连接到第三个对象中?

【问题讨论】:

标签: r dplyr


【解决方案1】:

这就是我将如何重写你的代码。

管道有一个技巧,可以使用. 将LHS 放在RHS 的多个位置。这使您无需分配中间对象即可进行连接。我还使用了更多步骤来实现不同的清晰度平衡而不是重复自己,例如在count() 中进行所有分组并使用其name 参数,使用mutate_at 在加入后进行所有格式化,以及使用str_gluescales::percent 使字符串格式更具可读性。

所有这些在某种程度上都是一个偏好问题,但我认为避免中间分配(以及必须命名所述对象的负担)可以通过以下方法解决。

library(tidyverse)
set.seed(500)
dat <- tibble(
  treatment = sample(c("Group1", "Group2", "Group3"), 100, replace = TRUE),
  recruitment_strategy = sample(c("Strategy 1", "Strategy 2", "Strategy 3", "Strategy 4", "Strategy 5"), 100, replace = TRUE),
  Variable_A = rnorm(100),
  Variable_B = rnorm(100),
  Variable_C = rnorm(100)
)

dat %>%
  inner_join(
      x = count(., treatment, recruitment_strategy) %>% spread(treatment, n),
      y = count(., recruitment_strategy, name = "Overall_dataset"),
      by = "recruitment_strategy"
  ) %>%
  mutate_at(
    .vars = vars(-recruitment_strategy),
    .funs = ~ str_glue("{.} ({scales::percent(. / sum(.), accuracy = 1)})")
  )
#> # A tibble: 5 x 5
#>   recruitment_strategy Group1  Group2   Group3  Overall_dataset
#>   <chr>                <glue>  <glue>   <glue>  <glue>         
#> 1 Strategy 1           2 (6%)  13 (30%) 4 (16%) 19 (19%)       
#> 2 Strategy 2           8 (26%) 6 (14%)  6 (24%) 20 (20%)       
#> 3 Strategy 3           6 (19%) 12 (27%) 3 (12%) 21 (21%)       
#> 4 Strategy 4           9 (29%) 4 (9%)   5 (20%) 18 (18%)       
#> 5 Strategy 5           6 (19%) 9 (20%)  7 (28%) 22 (22%)

reprex package (v0.3.0) 于 2019 年 11 月 10 日创建

【讨论】:

    猜你喜欢
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多