这是一种避免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 日创建。