按列X分组并汇总其余列的R dplyr。

3

我将使用以下数据集作为示例:

       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()) 只给出了数量,但是当我尝试添加mutate并为每个性别收集计数时,会出现错误。

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

我需要在group_by中包含所有列以便以后访问总和或计数吗?还是有更好的方法来解决这个问题?

2个回答

4

一种选择是将数据聚合成“长”格式,并获取多个列的“计数”,将其展开为“宽”格式,然后与由“组”和“性别”计算的“年龄”的“平均值”进行连接。

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”也会出现警告? - add-semi-colons
@Null-Hypothesis 这个解决方案是基于你提供的示例的。可能在原始数据集中存在重复行,因此需要一个按序列分组的列。 - akrun

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 软件包 (v0.2.0) 在 2018-03-05 创建的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接