Разделение многострочных транзакций на основе значений строк

У меня есть набор данных о розничных транзакциях, который выглядит так:

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 типа строк

  1. Тип A: Подробная строка (строки) транзакции. Транзакция может иметь один или несколько типов.A ряды.
  2. Тип Z: Строка заголовка транзакции. Транзакция может иметь только 1 ТипZ ряд.

Идеально для TRANSID, сумма GROSS AMNTs в типе A строки должны равняться GROSS AMNT в типе Z ряд.

В примере это верно для TRANSID=123, но не для TRANSID=126.

Мой вопрос: как отделить TRANSIDs который имеет
GROSS AMNTs в типе A строки = GROSS AMNTs в типе 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)
Другие вопросы по тегам