创建具有按行类别汇总的多个变量的交叉表
Creating Crosstable with Multiple Variables Summarized by Row Categories
我有兴趣按样本类别总结几个结果并将其全部呈现在一个 table 中。输出类似于:
vs
am
cyl
0
1
0
1
4
1
10
3
8
6
3
4
4
3
8
14
0
12
2
我是否能够合并(cbind
")由以下人员生成的 tables:
ftable(mtcars$cyl, mtcars$vs)
并由:
ftable(mtcars$cyl, mtcars$am)
crosstable()
and CrossTable()
包显示了希望,但我看不出如何在不嵌套的情况下将其扩展到多组列。
如 所示,ftable
可以接近:
ftable(vs + am ~ cyl, mtcars)
除了也在 vs
.
中嵌套 am
类似地,dplyr
通过
接近
library(dplyr)
mtcars %>%
group_by(cyl, vs, am) %>%
summarize(count = n())
或更复杂的东西,例如
但我有几个变量要呈现,这种嵌套破坏了在我的案例中进行总结的能力。
也许 可以在比我聪明的人手中工作?
蒂娅!
foo = function(df, grp, vars) {
lapply(vars, function(nm) {
tmp = as.data.frame(as.matrix(ftable(reformulate(grp, nm), df)))
names(tmp) = paste0(nm, "_", names(tmp))
tmp
})
}
do.call(cbind, foo(mtcars, "cyl", c("vs", "am", "gear")))
# vs_0 vs_1 am_0 am_1 gear_3 gear_4 gear_5
# 4 1 10 3 8 1 8 2
# 6 3 4 4 3 2 4 1
# 8 14 0 12 2 12 0 2
基于purrr::map_dfc
和tidyr::pivot_wider
的解决方案:
library(tidyverse)
map_dfc(c("vs", "am", "gear"), ~ mtcars %>% pivot_wider(id_cols = cyl,
names_from = .x, values_from = .x, values_fn = length,
names_prefix = str_c(.x, "_"), names_sort = T, values_fill = 0) %>%
{if (.x != "vs") select(.,-cyl) else .}) %>% arrange(cyl)
#> This message is displayed once per session.
#> # A tibble: 3 × 8
#> cyl vs_0 vs_1 am_0 am_1 gear_3 gear_4 gear_5
#> <dbl> <int> <int> <int> <int> <int> <int> <int>
#> 1 4 1 10 3 8 1 8 2
#> 2 6 3 4 4 3 2 4 1
#> 3 8 14 0 12 2 12 0 2
我有兴趣按样本类别总结几个结果并将其全部呈现在一个 table 中。输出类似于:
vs | am | |||
---|---|---|---|---|
cyl | 0 | 1 | 0 | 1 |
4 | 1 | 10 | 3 | 8 |
6 | 3 | 4 | 4 | 3 |
8 | 14 | 0 | 12 | 2 |
我是否能够合并(cbind
")由以下人员生成的 tables:
ftable(mtcars$cyl, mtcars$vs)
并由:
ftable(mtcars$cyl, mtcars$am)
crosstable()
and CrossTable()
包显示了希望,但我看不出如何在不嵌套的情况下将其扩展到多组列。
如 ftable
可以接近:
ftable(vs + am ~ cyl, mtcars)
除了也在 vs
.
am
类似地,dplyr
通过
library(dplyr)
mtcars %>%
group_by(cyl, vs, am) %>%
summarize(count = n())
或更复杂的东西,例如
但我有几个变量要呈现,这种嵌套破坏了在我的案例中进行总结的能力。
也许
蒂娅!
foo = function(df, grp, vars) {
lapply(vars, function(nm) {
tmp = as.data.frame(as.matrix(ftable(reformulate(grp, nm), df)))
names(tmp) = paste0(nm, "_", names(tmp))
tmp
})
}
do.call(cbind, foo(mtcars, "cyl", c("vs", "am", "gear")))
# vs_0 vs_1 am_0 am_1 gear_3 gear_4 gear_5
# 4 1 10 3 8 1 8 2
# 6 3 4 4 3 2 4 1
# 8 14 0 12 2 12 0 2
基于purrr::map_dfc
和tidyr::pivot_wider
的解决方案:
library(tidyverse)
map_dfc(c("vs", "am", "gear"), ~ mtcars %>% pivot_wider(id_cols = cyl,
names_from = .x, values_from = .x, values_fn = length,
names_prefix = str_c(.x, "_"), names_sort = T, values_fill = 0) %>%
{if (.x != "vs") select(.,-cyl) else .}) %>% arrange(cyl)
#> This message is displayed once per session.
#> # A tibble: 3 × 8
#> cyl vs_0 vs_1 am_0 am_1 gear_3 gear_4 gear_5
#> <dbl> <int> <int> <int> <int> <int> <int> <int>
#> 1 4 1 10 3 8 1 8 2
#> 2 6 3 4 4 3 2 4 1
#> 3 8 14 0 12 2 12 0 2