Условное суммирование по фреймам данных в R - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь повторить функциональность SUMIFS в R. У меня есть два фрейма данных.

Фрейм данных 1

allReported

ID       employeeGroup
1093     Bargaining Unit
1093     Management
1093     Non-Union
55       Bargaining Unit
55       Management
55       Non-Union

Фрейм данных 2

employeeCompSummary

ID       employeeGroup      statBenefits    regularWages
1093     Management         500.00          10000.00
1093     Management         200.00          60000.00
1093     Bargaining Unit    100.00          20000.00
1093     Bargaining Unit    150.00          30000.00
1093     Non-Union          500.00          60000.00
55       Bargaining Unit    750.00          65000.00
55       Bargaining Unit    500.00          75000.00
55       Management         250.00          45000.00
55       Management         850.00          90000.00

Я пытаюсь суммировать statBenefits (а затем и обычную заработную плату), чтобы создать новую таблицу, которая бывыдать следующий результат:

ID       employeeGroup          statBenefits
1093     Bargaining Unit        250.00
1093     Management             700.00
1093     Non-Union              500.00
55       Bargaining Unit        1250.00
55       Management             1100.00
55       Non-Union              0.00

Я пробовал следующее:

library(data.table)
setDT(allReported)[, list(total=sum(statbenefits)), list(employeeCompSummary, employeeGroup)]

и получаю следующую ошибку:

Error in `[.data.table`(setDT(allReported), , list(total = sum(statbenefits)),  :   column or expression 1 of 'by' or 'keyby' is type list. Do not quote column names. Usage: DT[,sum(colC),by=list(colA,month(colB))]

Я также пробовал:

sumTest <- aggregate(allReported, by = list(employeeCompSummary), sum)

и получил следующую ошибку:

**Error in aggregate.data.frame(allReported, by = list(employeeCompSummary),  :   arguments must have same length**

Любая помощь, которую кто-либо может оказать, будет очень признательна.Я посмотрел на другие вопросы, которые, кажется, имеют дело с этим, но не смогли найти ответ, который работает.Я буду выполнять эту задачу над несколькими вещами, поэтому мне было интересно, есть ли простой метод, который кто-нибудь знает.Как всегда, заранее спасибо замечательному сообществу здесь о переполнении стека.

Отредактируйте dput () двух примеров таблиц:

allReported <- structure(list(ID = c(1093, 1093, 1093, 1093, 1093, 55, 55, 55,55), employeeGroup = c("Management", "Management", "Bargaining Unit","Bargaining Unit", "Non-Union", "Bargaining Unit", "Bargaining Unit","Management", "Management"), statBenefits = c(500, 200, 100,150, 500, 750, 500, 250, 850), regularWages = c(10000, 60000,20000, 30000, 60000, 65000, 75000, 45000, 90000)), row.names = c(NA,-9L), class = c("tbl_df", "tbl", "data.frame"))

employeeCompSummary <- structure(list(ID = c(1093, 1093, 1093, 55, 55, 55), employeeGroup =c("Bargaining Unit","Management", "Non-Union", "Bargaining Unit", "Management", "Non-Union")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

 . 

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Для этого можно использовать пакеты dplyr и magrittr (для %>%) -

library(dplyr)
library(magrittr)

df1 <- structure(list(ID = c(1093, 1093, 1093, 55, 55, 55), employeeGroup =c("Bargaining Unit","Management", "Non-Union", "Bargaining Unit", "Management", "Non-Union")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

df2 <- structure(list(ID = c(1093, 1093, 1093, 1093, 1093, 55, 55, 55,55), employeeGroup = c("Management", "Management", "Bargaining Unit","Bargaining Unit", "Non-Union", "Bargaining Unit", "Bargaining Unit","Management", "Management"), statBenefits = c(500, 200, 100,150, 500, 750, 500, 250, 850), regularWages = c(10000, 60000,20000, 30000, 60000, 65000, 75000, 45000, 90000)), row.names = c(NA,-9L), class = c("tbl_df", "tbl", "data.frame"))

result <- left_join(df1, df2, by = c("ID", "employeeGroup")) %>%
  group_by(ID, employeeGroup) %>%
  summarize(
    statBenefits = sum(statBenefits, na.rm = T),
    regularWages = sum(regularWages, na.rm = T)
  )
result
0 голосов
/ 20 сентября 2018

Я бы сделал ...

library(data.table)

# don't use setDT, since who knows if it works on tibbeldies
ar = data.table(allReported)
ecs = data.table(employeeCompSummary)

ecs[, total := ar[.SD, on=.(ID, employeeGroup), sum(x.statBenefits), by=.EACHI][, V1]]

     ID   employeeGroup total
1: 1093 Bargaining Unit   250
2: 1093      Management   700
3: 1093       Non-Union   500
4:   55 Bargaining Unit  1250
5:   55      Management  1100
6:   55       Non-Union    NA

Этот код добавляет столбцы к ecs, даже если OP запросил новую таблицу.Набор строк идентичен между новой таблицей и ecs, поэтому кажется, что тратить ментальную энергию на них обоих.Отбросить столбцы позже просто.

Если вы хотите узнать, как работает это "обновление объединения", попробуйте работать в обратном направлении ...

ar[ecs, on=.(ID, employeeGroup), sum(x.statBenefits), by=.EACHI]

# or

ar[ecs, on=.(ID, employeeGroup)]

Примечание. SD == ecs в оригиналекод.Смотри ?.SD.

0 голосов
/ 20 сентября 2018

Редактирование на основе вашего комментария: Один из способов сделать это - использовать data.table таким образом

library(data.table)
dt1 <- data.table(structure(list(ID = c(1093, 1093, 1093, 1093, 1093, 55, 55, 55,55), 
               employeeGroup = c("Management", "Management", "Bargaining Unit","Bargaining Unit", "Non-Union", "Bargaining Unit", "Bargaining Unit","Management", "Management"), statBenefits = c(500, 200, 100,150, 500, 750, 500, 250, 850), regularWages = c(10000, 60000,20000, 30000, 60000, 65000, 75000, 45000, 90000)), 
          row.names = c(NA,-9L), class = c("tbl_df", "tbl", "data.frame")), key = c("ID", "employeeGroup"))

dt2 <- data.table(structure(list(ID = c(1093, 1093, 1093, 55, 55, 55), employeeGroup =c("Bargaining Unit","Management", "Non-Union", "Bargaining Unit", "Management", "Non-Union")), 
          row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame")), key = c("ID", "employeeGroup"))



dt1[dt2][, lapply(.SD, sum), .SDcols = c("statBenefits", "regularWages"), by = c("ID", "employeeGroup")]

, что дает

ID   employeeGroup statBenefits regularWages
1:   55 Bargaining Unit         1250       140000
2:   55      Management         1100       135000
3:   55       Non-Union           NA           NA
4: 1093 Bargaining Unit          250        50000
5: 1093      Management          700        70000
6: 1093       Non-Union          500        60000

. Позже вы можете заменить значения NA на 0

...