小计取决于 r 中的多列

Subtotal depending on multiple columns in r

这是一个测试table:

df <- read.table(text="
           str1 str2    name    t   y   x
             a  yes bas 23  323 21
             b  no  aasd    23  54  33
             a  no  asd 2   43  23
             b  yes hggf    43  123 55
             b  no  jgd 1   12  11
             b  yes qw  32  12  12
             a  yes rrrr    45  22  32
             a  no  ggg 121 11  43
             ",
             header = TRUE)

借助here我们可以得到这样的小计

library(janitor)
library(purrr)
library(dplyr)
df<-df %>% 
  split(.[,"str1"]) %>% ## splits each change in cyl into a list of dataframes 
  map_df(., janitor::adorn_totals)

但我的问题是如何根据 str2 中的组在每组列 str1 中获取小计。它需要这样的数据框:

非常感谢任何帮助

P.S重要的是x列在每组中按降序排列

我们可以按两列拆分,然后根据 'str1'、'str2'

中的值更改 'Total' 的名称
library(dplyr)
library(janitor)
library(purrr)
library(stringr)
df %>% 
   group_split(str1, str2) %>% 
   map_dfr(~ .x %>% 
        janitor::adorn_totals(.) %>% 
        mutate(str1 = replace(str1, n(), str_c(str1[n()], "_", 
           first(str1), "_", first(str2)))))

或者,使用与第一次拆分相同的语法,您可以:

library(janitor)
library(purrr)
library(dplyr)
df %>% arrange(x) %>%
  split(.[,c("str2","str1")]) %>% 
  map_df(., janitor::adorn_totals)

  str1 str2 name   t   y  x
     a   no  asd   2  43 23
     a   no  ggg 121  11 43
 Total    -    - 123  54 66
     a  yes  bas  23 323 21
     a  yes rrrr  45  22 32
 Total    -    -  68 345 53
     b   no  jgd   1  12 11
     b   no aasd  23  54 33
 Total    -    -  24  66 44
     b  yes   qw  32  12 12
     b  yes hggf  43 123 55
 Total    -    -  75 135 67

如果您不介意“总计”行的位置稍有不同,可以使用 data.table::rollup。带有 NA 的行是由非 NA 列的值标识的组的总计。

library(data.table)
setDT(df)

group_vars <- head(names(df), 3)
df_ru <- 
  rollup(df, j = lapply(.SD, sum), by = group_vars, 
         .SDcols = tail(names(df), 3))

setorderv(df_ru, group_vars)[-1]
#>     str1 str2 name   t   y   x
#>  1:    a <NA> <NA> 191 399 119
#>  2:    a   no <NA> 123  54  66
#>  3:    a   no  asd   2  43  23
#>  4:    a   no  ggg 121  11  43
#>  5:    a  yes <NA>  68 345  53
#>  6:    a  yes  bas  23 323  21
#>  7:    a  yes rrrr  45  22  32
#>  8:    b <NA> <NA>  99 201 111
#>  9:    b   no <NA>  24  66  44
#> 10:    b   no aasd  23  54  33
#> 11:    b   no  jgd   1  12  11
#> 12:    b  yes <NA>  75 135  67
#> 13:    b  yes hggf  43 123  55
#> 14:    b  yes   qw  32  12  12

reprex package (v2.0.0)

于 2021-06-05 创建