根据2个单独的列汇总值

时间:2018-10-29 14:00:03

标签: r dataframe aggregate

我有一个df(下面部分列出)。

ArrayList#get()

我正在尝试根据以下条件将 account company sum 1 202003 B01 40.50 2 208001 B01 -71596.73 3 280250 B01 -6652.70 4 200001 B13 44362.77 5 202001 B13 13874.25 6 204001 B13 5744.20 7 204102 B13 295.00 8 285091 B13 317145.15 9 286101 B13 11471.13 10 298001 B13 396096.50 列中的数字添加到新的数据框中: 对于每个公司(df1$sumB01),我需要为B13中以^ 20开头的所有帐户汇总df1$sum列,并将其命名为df1$accounts(因此在此示例中,公司df2$Expenses1的名称为202003208001)。

另外,我需要汇总所有以^ 28和^ 29开头的帐户,并将其命名为B01(因此,对于公司df2$Expenses2,它只会是帐户B01,对于公司{ {1}}是帐户280250B13285091的总和。

最终,新的数据帧286101应该看起来像这样:

298001

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

使用tidyverse

library(tidyverse)
df %>% 
  group_by(company) %>% 
  summarise(Expenses1 = sum(sum*grepl('^20', account)),
            Expenses2 = sum(sum*grepl('^28|^29', account)))
# # A tibble: 2 x 3
#   company Expenses1 Expenses2
#   <chr>       <dbl>     <dbl>
# 1 B01        -71556   -  6653
# 2 B13         64276    724713

带有数据表

library(data.table)
setDT(df)

df[, lapply(c(Expenses1 = '^20', 
              Expenses2 = '^28|^29'), 
            function(patt) sum(sum*grepl(patt, account)))
   , by = company]

#    company Expenses1 Expenses2
# 1:     B01 -71556.23   -6652.7
# 2:     B13  64276.22  724712.8

如果实际上只有两个组,则可以创建另一个分组变量,然后使用dcastspread例如

df[, .(Expenses = sum(sum))
   , by = .(company, 
            acct_type = paste0('Expenses_', ifelse(grepl('^20', account), '20', 'other')))] %>% 
  dcast(company ~ acct_type)


#    company Expenses_20 Expenses_other
# 1:     B01   -71556.23        -6652.7
# 2:     B13    64276.22       724712.8