Агрегирование значений на основе 2 отдельных столбцов - PullRequest
0 голосов
/ 29 октября 2018

У меня есть df (частично указан ниже).

    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$sum в новый фрейм данных на основе следующих критериев: Для каждой компании (B01 и B13) мне нужно объединить столбец df1$sum для всех учетных записей в df1$accounts, начиная с ^ 20, и назвать его df2$Expenses1 (поэтому в этом примере это будет 202003 и 208001 для компании B01).

Отдельно мне нужно объединить все учетные записи, начинающиеся с ^ 28 и ^ 29, и назвать его df2$Expenses2 (поэтому для компании B01 это будет только учетная запись 280250, а для компании B13 это будет сумма счетов 285091, 286101 и 298001).

В конечном итоге новый фрейм данных df2 должен выглядеть примерно так:

Company   Expenses1   Expenses2
 B01     -71,556.23    -6,652.7
 B13      64,276.22  724,712.78    

Буду очень признателен за помощь!

1 Ответ

0 голосов
/ 29 октября 2018

с тидиверсом

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

Если у вас действительно есть только две группы, вы можете создать другую переменную группировки, а затем использовать dcast или spread, например,

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
...