在dplyr链中添加边距行总计

Jon*_*nny 22 r dplyr

我想添加整体摘要行,同时使用dplyr按组计算摘要.我发现了各种问题,询问如何做到这一点,例如这里,这里这里,但没有明确的解决方案.一种可能的方法是执行count两次并绑定行:

mtcars %>% 
  count(cyl, gear) %>% 
  bind_rows(
    count(mtcars, gear)
  )
Run Code Online (Sandbox Code Playgroud)

几乎产生我需要的东西(最左边的列有NAs而不是'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
Run Code Online (Sandbox Code Playgroud)

我错过了一个更简单/内置的解决方案吗?

Sam*_*rke 22

使用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
Run Code Online (Sandbox Code Playgroud)

要从帖子中获取帖子中的"长"表单,请添加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
Run Code Online (Sandbox Code Playgroud)

自我提升警报,我写了这个包 - 添加这个答案b/c这是一个真正有效的解决方案.

  • 感谢您提供额外的方法建议。我最近开始使用管理员,主要用于 clean_names()、excel_numeric_to_date() 和 remove_empty(),所有这些对我的日常工作都非常有帮助。我现在也将添加这些功能......恭喜你获得了一个很棒的包! (3认同)

akr*_*run 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
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@akrun,这非常有效.我不确定`do`调用​​是否必要 - "mtcars%>%count(cyl,gear)%>%ungroup()%>%mutate(cyl = as.character(cyl))%>%bind_rows(cbind (cyl ='Total',count(mtcars,gear)))`也可以.我会等着看是否有人提供内置的'dplyr`答案,并且会在24小时内接受.非常感谢 (2认同)

tma*_*tny 8

这是对接受的答案的看法,使用 dplyr 1.0.0 和 tidyr 1.0.0 中引入的新功能。

我们使用新的tidyr::pivot_wider. 然后使用新的dplyr::rowwisedplyr::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
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于 2020 年 4 月 7 日创建


Bis*_*est 7

添加@ 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
Run Code Online (Sandbox Code Playgroud)

这也可以加倍,以便为展布生成总行.

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
Run Code Online (Sandbox Code Playgroud)