Разделение многострочных транзакций на основе значений строк
У меня есть набор данных о розничных транзакциях, который выглядит так:
TRANSID GROSS AMNT TRANSROWTYPE
123 50 Z
123 20 A
123 30 A
126 90 Z
126 20 A
126 30 A
126 20 A
… .. .
Где,
• TRANDIS
это идентификатор транзакции
• GROSS AMNT
это общая сумма для строки транзакции
• TRANSROWTYPE
- это тип строки для транзакции.
Все транзакции имеют 2 типа строк
- Тип
A
: Подробная строка (строки) транзакции. Транзакция может иметь один или несколько типов.A
ряды. - Тип
Z
: Строка заголовка транзакции. Транзакция может иметь только 1 ТипZ
ряд.
Идеально для TRANSID
, сумма GROSS AMNT
s в типе A
строки должны равняться GROSS AMNT
в типе Z
ряд.
В примере это верно для TRANSID=123
, но не для TRANSID=126
.
Мой вопрос: как отделить TRANSIDs
который имеетGROSS AMNTs
в типе A
строки = GROSS AMNT
s в типе Z
ряд из тех, где два не равны?
Мне особенно интересно найти решение, используя dplyr
Спасибо заранее.
2 ответа
Да, вы можете сделать это одним снимком с dplyr. Сначала вы суммируете, чтобы сжать несколько строк одного типа. Это повлияет только на строки типа A, так как строки Z в любом случае встречаются только один раз для каждого идентификатора перехода.
Сразу после подведения итогов вы выполняете pivot_wider(), чтобы значения A и Z могли находиться рядом в одной строке, что упрощает сравнение и фильтрацию только тех, которые соответствуют вашим критериям.
retail %>%
group_by(TRANSID, TRANSROWTYPE) %>%
summarise(TOTAL.AMT = sum(`GROSS AMNT`)) %>%
ungroup() %>%
pivot_wider(names_from = "TRANSROWTYPE", values_from = "TOTAL.AMT") %>%
subset(A != Z)
Есть много способов получить желаемый результат с помощью tidyverse
package, так что вот еще один вариант.
library(tidyverse)
df %>%
#Group by TRANS and TRANSROWTYPE
group_by(TRANSID, TRANSROWTYPE) %>%
#Get the sum of GROSS AMT by ID and row type
summarise(sum_amt = sum(`GROSS AMNT`)) %>%
#Ungroup
ungroup() %>%
#Group by ID
group_by(TRANSID) %>%
#Get distinct values
distinct(sum_amt) %>%
#Remove rows where sum_amt is the same for A and Z per ID (i.e., n = 1)
#and stay only with rows where there are 2 distinct values
filter(n() >= 2)