Вытащите все транзакции после обнаружения плохой кредитной истории

Ниже приведен небольшой набор данных о транзакциях с идентификатором, датой месяца, фиктивной переменной Bad_Credit или без нее. Я хотел бы вытащить все транзакции после начала плохой кредитной истории. В столбце OUTPUT указан правильный результат, то есть строки 1,2,3,5,6,8,10.

Это просто пример, может быть тысячи строк. SQL, R, SPSS будут работать. Спасибо.

ДАТА ИДЕНТИФИКАТОР Bad_CREDIT ВЫХОД 12 А 1 1 15 А 1 1 18 А 0 1 2 Б 0 0 10 Б 1 1 20 Б 0 1 5 С 0 0 15 С 1 1 1 Д 0 0 9 Е 1 1

Кстати, плохая кредитная история не обязательно должна быть связана со второй транзакцией, это может быть третья или более поздняя...

Gan Ren 15.12.2020 04:02

Кто-нибудь знает, как использовать SPSS, чтобы сделать это?

Gan Ren 15.12.2020 05:54
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
2
63
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Если я правильно понимаю, вы можете использовать оконные функции:

select t.*
from (select t.*,
             min(case when bad_credit = 1 then date end) over (partition by id) as min_bd_date
      from t
     ) t
where date >= min_bd_date;

Вы также можете сделать это с помощью коррелированного подзапроса:

select t.*
from t
where t.date >= (select min(t2.date)
                 from t t2
                 where t2.id = t.id and
                       t2.bad_credit = 1
                );

Спасибо. Прекрасно работает.

Gan Ren 15.12.2020 05:56

@ГанРен. . . Есть ли причина, по которой вы не приняли ответ?

Gordon Linoff 16.12.2020 19:28

Если это в базе данных, то я думаю, что SQL, вероятно, лучше всего подходит для решения этой проблемы. Однако, если он у вас уже есть в R, то...

Вот метод R, использующий dplyr:

library(dplyr)
dat %>%
  group_by(ID) %>%
  mutate(OUTPUT2 = +cumany(Bad_CREDIT)) %>%
  ungroup()
# # A tibble: 10 x 5
#     DATE ID    Bad_CREDIT OUTPUT OUTPUT2
#    <int> <chr>      <int>  <int>   <int>
#  1    12 A              1      1       1
#  2    15 A              1      1       1
#  3    18 A              0      1       1
#  4     2 B              0      0       0
#  5    10 B              1      1       1
#  6    20 B              0      1       1
#  7     5 C              0      0       0
#  8    15 C              1      1       1
#  9     1 D              0      0       0
# 10     9 E              1      1       1

Поскольку это фактически простая операция группировки, то базовые решения R и data.table столь же просты.

+ave(dat$Bad_CREDIT, dat$ID, FUN=cumany)
#  [1] 1 1 1 0 1 1 0 1 0 1

library(data.table)
datDT <- as.data.table(dat)
datDT[, OUTPUT2 := +cumany(Bad_CREDIT), by = .(ID)]

Спасибо. Я не силен в dplyr, использую только sqldf :)

Gan Ren 15.12.2020 05:56

Вы можете arrange данные с помощью ID и DATE и для каждого ID присвоить 0, если первое значение Bad_CREDIT равно 0.

library(dplyr)

df %>%
  arrange(ID, DATE) %>%
  group_by(ID) %>%
  mutate(OUTPUT = as.integer(!(first(Bad_CREDIT) == 0 & row_number() == 1)))

#    DATE ID    Bad_CREDIT OUTPUT
#   <int> <chr>      <int>  <int>
# 1    12 A              1      1
# 2    15 A              1      1
# 3    18 A              0      1
# 4     2 B              0      0
# 5    10 B              1      1
# 6    20 B              0      1
# 7     5 C              0      0
# 8    15 C              1      1
# 9     1 D              0      0
#10     9 E              1      1

данные

df <- structure(list(DATE = c(12L, 15L, 18L, 2L, 10L, 20L, 5L, 15L, 
1L, 9L), ID = c("A", "A", "A", "B", "B", "B", "C", "C", "D", 
"E"), Bad_CREDIT = c(1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L, 0L, 1L)), 
row.names = c(NA, -10L), class = "data.frame")

Спасибо. Я не силен в dplyr, использую только sqldf :)

Gan Ren 15.12.2020 05:55

Вы можете использовать EXISTS следующим образом:

select t.* from your_table t
where exists
     (select 1
        from your_table tt
       where t.id = tt.id
         and t.date >= tt.date 
         and tt.bad_credit = 1);

Спасибо, очень ценю это.

Gan Ren 15.12.2020 05:56

Это для SPSS:

sort cases by ID date.
compute PullOut=Bad_CREDIT.
if $casenum>1 and ID=lag(ID) and lag(PullOut)=1 PullOut=1.
exe.

Другие вопросы по теме