【问题标题】:R dplyr group by column X and summarize rest of the columnsR dplyr 按 X 列分组并总结其余列
【发布时间】:2018-03-05 23:21:23
【问题描述】:

我以以下数据集为例:

       Age      Gender  CarType     Group   Education
1      46        Male      Sedan     1        BS
2      37        Male      SUV       1        MS
3      47      Female      Sedan     2        PhD
4      20        Male      SUV       2        HS
5      41        Male      SUV       1        MS 
6      52        Male      Sedan     2        MS

我的目标是使用Group 变量进行分组,然后按组显示每列的统计信息。

Group   Male  Female Female-Mean-age Male-Mean-AGE Sedan SUV PhD BS MS
 1       3      0         0               41.3      1     2    0  1  2

df %>% group_by(Group) %>% summarise(n = n()) 只是给出计数,但是当我尝试为每个性别添加变异和收集计数时,我得到了错误

df %>% group_by(Group, Gender) %>% summarize(n=n()) %>% mutate(male = count('Male'))

我是否需要在 group_by 中包含所有列,以便稍后访问 sum 或 count 或解决此问题的最佳方法是什么?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    一种选择是将gather 转换为“长”格式并获取多列的“计数”,将spread 转换为“宽”格式,然后与“年龄”的mean 进行连接按“组”和“性别”计算

    library(tidyr)
    library(dplyr)
    res1 <- gather(df1, key, val, Gender, CarType, Education) %>% 
                   group_by(Group, key, val) %>% 
                   summarise(n = n()) %>%
                   ungroup %>% select(-key) %>% 
                   spread(val, n, fill = 0)
    res2 <- df1 %>% 
               group_by(Group, Gender) %>%
               summarise(Age_Mean = mean(Age))  %>% 
               mutate(Gender = paste0(Gender, "_Mean")) %>%
               spread(Gender, Age_Mean, fill = 0)
    left_join(res1, res2)
    # A tibble: 2 x 11
    #  Group    BS Female    HS  Male    MS   PhD Sedan   SUV Female_Mean Male_Mean
    #  <int> <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>       <dbl>     <dbl>
    #1     1  1.00   0     0     3.00  2.00  0     1.00  2.00         0        41.3
    #2     2  0      1.00  1.00  2.00  1.00  1.00  2.00  1.00        47.0      36.0
    

    【讨论】:

    • 收到Error: Duplicate identifiers for rows 警告我应该收集所有列还是因为即使gather 也会发出警告
    • @Null-Hypothesis 此解决方案基于您在此处提供的示例。可能在原始数据集中,存在重复的行,您需要按序列列分组。
    【解决方案2】:

    这是一种避免left_join 和中间对象的替代方法,但您可以自行决定是否觉得这更容易理解或阅读。在不知道数据的形状的情况下,很难判断什么是最简单的。这个方法只需要额外的一行或两行你想要做的额外不同的摘要函数,而如果你想要最大年龄,上面需要另一个left_join和另一个df。但是,如果您有更多变量都需要计数,则上述操作会更容易,因为它不会为具有相同汇总函数的更多变量添加行。

    该方法基本上是使用mutate 将正确的分组摘要添加为新列,然后使用spread 为每个创建正确的列名称。我们可以通过调用summarise 将所有内容减少Group。我使用median,因为我们选择什么汇总函数并不重要,此时所有变量都应该有一个值,而mean 产生NaN,这有点烦人。

    注意最后一行mutate_at 将计数中的所有NA 变为0。但是,我选择不替换mean_age_Female 中的NA,因为NA 意味着与0 不同的东西。这是当前此解决方案与其他解决方案之间的输出差异,尽管这是一个小修复。

    library(tidyverse)
    tbl <- read_table2(
      "Age      Gender  CarType     Group   Education
      46        Male      Sedan     1        BS
      37        Male      SUV       1        MS
      47      Female      Sedan     2        PhD
      20        Male      SUV       2        HS
      41        Male      SUV       1        MS 
      52        Male      Sedan     2        MS"
    )
    #> Warning: 2 parsing failures.
    #> row # A tibble: 2 x 5 col     row col       expected  actual        file         expected   <int> <chr>     <chr>     <chr>         <chr>        actual 1     5 <NA>      5 columns 6 columns     literal data file 2     6 Education ""        embedded null literal data
    
    tbl %>%
      add_count(Group, Gender) %>% # Add all summary statistics as columns
      add_count(Group, CarType) %>%
      add_count(Group, Education) %>%
      group_by(Group, Gender) %>%
      mutate(., mAge = mean(Age)) %>%
      mutate(Gender2 = str_c("mean_age_", Gender)) %>%
      spread(Gender, n) %>% # Convert all to new columns
      spread(Gender2, mAge) %>%
      spread(CarType, nn) %>%
      spread(Education, nnn) %>%
      group_by(Group) %>% # Collapse to one row per group
      summarise_at(vars(-Age), function(x) median(x, na.rm = TRUE)) %>%
      mutate_at(vars(-starts_with("mean_age_")), function(x) replace_na(x, 0))
    #> # A tibble: 2 x 11
    #>   Group Female  Male mean_age_Female mean_age_Male Sedan   SUV    BS    HS
    #>   <dbl>  <dbl> <dbl>           <dbl>         <dbl> <dbl> <dbl> <dbl> <dbl>
    #> 1  1.00   0     3.00            NA            41.3  1.00  2.00  1.00  0   
    #> 2  2.00   1.00  2.00            47.0          36.0  2.00  1.00  0     1.00
    #> # ... with 2 more variables: MS <dbl>, PhD <dbl>
    

    由reprex package (v0.2.0) 于 2018 年 3 月 5 日创建。

    【讨论】:

      猜你喜欢
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      相关资源
      最近更新 更多