我想添加整体摘要行,同时使用dplyr按组计算摘要。我发现了各种问题,询问如何做到这一点,例如: here,here和here,但没有明确的解决方案。一种可能的方法是执行count
两次并绑定行:
mtcars %>%
count(cyl, gear) %>%
bind_rows(
count(mtcars, gear)
)
几乎产生我需要的东西(最左边的列有NA而不是' Total'或类似的):
cyl gear n
<dbl> <dbl> <int>
1 4 3 1
2 4 4 8
3 4 5 2
4 6 3 2
5 6 4 4
6 6 5 1
7 8 3 12
8 8 5 2
9 NA 3 15
10 NA 4 12
11 NA 5 5
我错过了一个更容易/内置的解决方案吗?
答案 0 :(得分:16)
使用janitor包中的adorn_totals():
library(janitor)
mtcars %>%
tabyl(cyl, gear) %>%
adorn_totals("row")
cyl 3 4 5
4 1 8 2
6 2 4 1
8 12 0 2
Total 15 12 5
要从帖子中获取帖子中的“长”表单,请将tidyr::gather()
添加到管道中:
mtcars %>%
tabyl(cyl, gear) %>%
adorn_totals("row") %>%
tidyr::gather(gear, n, 2:ncol(.), convert = TRUE)
cyl gear n
1 4 3 1
2 6 3 2
3 8 3 12
4 Total 3 15
5 4 4 8
6 6 4 4
7 8 4 0
8 Total 4 12
9 4 5 2
10 6 5 1
11 8 5 2
12 Total 5 5
自我推销提醒,我撰写了这个包 - 在这里添加这个答案b / c这是一个真正有效的解决方案。
答案 1 :(得分:8)
一个选项是使用do
mtcars %>%
count(cyl, gear) %>%
ungroup() %>%
mutate(cyl=as.character(cyl)) %>%
do(bind_rows(., data.frame(cyl="Total", count(mtcars, gear))))
#or replace the last 'do' step with
#bind_rows(cbind(cyl='Total', count(mtcars, gear))) #from @JonnyPolonsky's comments
# cyl gear n
# <chr> <dbl> <int>
#1 4 3 1
#2 4 4 8
#3 4 5 2
#4 6 3 2
#5 6 4 4
#6 6 5 1
#7 8 3 12
#8 8 5 2
#9 Total 3 15
#10 Total 4 12
#11 Total 5 5
答案 2 :(得分:6)
@ arkrun的回答是一个不容易添加为评论的答案:
虽然稍微复杂一点,但这种格式允许在数据框中进行先前的修改。在生成表之前存在更长的动词链时很有用。 (您想要更改名称,或只选择特定变量)
mtcars %>%
count(cyl, gear) %>%
ungroup() %>%
mutate(cyl=as.character(cyl))
bind_rows(group_by(.,gear) %>%
summarise(n=sum(n)) %>%
mutate(cyl='Total')) %>%
spread(cyl)
## A tibble: 3 x 5
# gear `4` `6` `8` Total
#* <dbl> <dbl> <dbl> <dbl> <dbl>
#1 3 1 2 12 15
#2 4 8 4 0 12
#3 5 2 1 2 5
这也可以加倍,以便为点差生成总行。
mtcars %>%
count(cyl, gear) %>%
ungroup() %>%
mutate(cyl=as.character(cyl),
gear = as.character(gear)) %>%
bind_rows(group_by(.,gear) %>%
summarise(n=sum(n)) %>%
mutate(cyl='Total')) %>%
bind_rows(group_by(.,cyl) %>%
summarise(n=sum(n)) %>%
mutate(gear='Total')) %>%
spread(cyl,n,fill=0)
# A tibble: 4 x 5
gear `4` `6` `8` Total
* <chr> <dbl> <dbl> <dbl> <dbl>
1 3 1 2 12 15
2 4 8 4 0 12
3 5 2 1 2 5
4 Total 11 7 14 32
答案 3 :(得分:5)
以下是接受的答案,它使用dplyr 1.0.0和tidyr 1.0.0中引入的新功能。
我们使用新的tidyr::pivot_wider
调整计数。然后使用新的dplyr::rowwise
和dplyr::c_across
对总计列的计数求和。
我们还可以使用tidyr::pivot_longer
来获得所需的长格式。
library(dplyr, warn.conflicts = FALSE)
library(tidyr)
cyl_gear_sum <- mtcars %>%
count(cyl, gear) %>%
pivot_wider(names_from = gear, values_from = n, values_fill = list(n = 0)) %>%
rowwise(cyl) %>%
mutate(gear_total = sum(c_across()))
cyl_gear_sum
#> # A tibble: 3 x 5
#> # Rowwise: cyl
#> cyl `3` `4` `5` gear_total
#> <dbl> <int> <int> <int> <int>
#> 1 4 1 8 2 11
#> 2 6 2 4 1 7
#> 3 8 12 0 2 14
# total as row
cyl_gear_sum %>%
pivot_longer(-cyl, names_to = "gear", values_to = "n")
#> # A tibble: 12 x 3
#> cyl gear n
#> <dbl> <chr> <int>
#> 1 4 3 1
#> 2 4 4 8
#> 3 4 5 2
#> 4 4 gear_total 11
#> 5 6 3 2
#> 6 6 4 4
#> 7 6 5 1
#> 8 6 gear_total 7
#> 9 8 3 12
#> 10 8 4 0
#> 11 8 5 2
#> 12 8 gear_total 14
由reprex package(v0.3.0)于2020-04-07创建
答案 4 :(得分:1)
如果您想拥有真正通用的解决方案,可以结合使用purrr :: map_df,base :: c和base :: sum
mtcars %>%
purrr::map_df(~c(.x, sum(.x, na.rm=TRUE))) %>%
tail
P.S。所有列必须为数字!
答案 5 :(得分:0)
这是我的建议。
注意。如果分组变量是数字变量,则它们不会在第3步中删除-因此,我将其突变为字符变量。
powerSetList <- function(df, ...) {
rje::powerSet(x = c(...))[-1] %>% lapply(function(x, tdf = df) group_by(tdf, .dots=x)) %>% c(list(tibble(df)), .)
}
mtcars %>%
mutate_at(vars("cyl", "gear"), as.character) %>%
powerSetList("cyl", "gear") %>%
map(~summarise_if(., is.numeric, .funs = mean)) %>%
bind_rows() %>%
replace_na(list(gear = "all gears",
cyl = "all cyls"))
答案 6 :(得分:0)
也许可行:
library(dplyr)
mtcars %>%
# convert cyl column as.character
mutate_at("cyl",as.character) %>%
# add a copy of the origina data with cyl column = 'TOTAL'
bind_rows(mutate(mtcars, cyl="total")) %>%
group_by(cyl) %>% summarise_all(sum)
答案 7 :(得分:0)
library(tidyverse)
#Pre-process mtcars
mtcars_pre <-
as_tibble(mtcars) %>% #remove rownames
select(cyl, gear) %>%
count(cyl, gear) %>% #add row totals
mutate(
cyl = as.character(cyl) #Convert to character in order to add "Total"
)
#> # A tibble: 8 x 3
#> cyl gear n
#> <chr> <dbl> <int>
#> 1 4 3 1
#> 2 4 4 8
#> 3 4 5 2
#> 4 6 3 2
#> 5 6 4 4
#> 6 6 5 1
#> 7 8 3 12
#> 8 8 5 2
mtcars_totals <-
mtcars_pre %>%
bind_rows(
mtcars_pre %>%
group_by(gear) %>%
summarise(across(where(is.numeric), ~ sum(.x, na.rm = TRUE))) %>%
mutate("cyl" = "Total")
) %>%
arrange(
gear
)
#> # A tibble: 11 x 3
#> cyl gear n
#> <chr> <dbl> <int>
#> 1 4 3 1
#> 2 6 3 2
#> 3 8 3 12
#> 4 Total 3 15
#> 5 4 4 8
#> 6 6 4 4
#> 7 Total 4 12
#> 8 4 5 2
#> 9 6 5 1
#> 10 8 5 2
#> 11 Total 5 5
由 reprex 包 (v2.0.0) 于 2021 年 7 月 13 日创建