ГД
Size: a a a
ГД
PU
PU
ГД
PU
PU
ГД
ГД
PU
AS
UT
ГД
IS
pipe
не имеет отношения к tidyverse
, это сам по себе отдельный пакет magrittr
data.table
%$%
, %T>%
, %>% {} ?S+
.М
IS
PU
IS
# Займ -- положительное значение, погашение -- отрицательное# Шаг 2. Расчитываем даты погашения каждого займа
total_users <- 100
events_dt <- tibble(
date = sample(
seq.Date(as.Date("2021-01-01"), as.Date("2021-04-30"), by = "1 day"),
total_users * 10,
replace = TRUE)
) %>%
# сделаем суммы кратными 50 р.
mutate(amount = (runif(n(), -2000, 1000)) %/% 50 * 50) %>%
# нашпигуем идентификаторами пользователей
mutate(user_id = sample(!!total_users, n(), replace = TRUE)) %>%
setDT(key = "date") %>%
# первая запись должна быть займом
.[.[, .I[1L], by = user_id]$V1, amount := abs(amount)] %>%
# для простоты оставим только одну операцию в день,
# иначе нельзя порядок определить и гранулярность до секунд надо спускать
# либо вводить порядковый номер займа и погашения
unique(by = c("user_id", "date"))
# инициализируем аккумулятор# Шаг 3. Считаем динамику задолженности по периоду
accu_dt <- events_dt[amount < 0, .(accu = cumsum(amount), date), by = user_id]
ff <- function(dt){
# на вход получаем матрицу пользователей и их платежей на заданную дату
# затягиваем суммы займов
accu_dt[dt, amount := i.amount, on = "user_id"]
accu_dt[is.na(amount) == FALSE, accu := accu + amount][accu > 0, accu := NA, by = user_id]
calc_dt <- accu_dt[!is.na(accu), head(date, 1), by = user_id]
# нанизываем обратно на входной data.frame, сохраняя порядок следования
calc_dt[dt, on = "user_id"]$V1
}
repay_dt <- events_dt[amount > 0] %>%
.[, repayment_date := ff(.SD), by = date] %>%
.[order(user_id, date)]
calcDebt <- function(report_date){
as_tibble(repay_dt) %>%
# выкидываем все, что уже погашено на дату отчета
filter(is.na(repayment_date) | repayment_date > !! report_date) %>%
mutate(delay = as.numeric(!!report_date - date)) %>%
# размечаем просрочки
mutate(tag = santoku::chop(delay, breaks = c(0, 31, 61, 90),
labels = c("< 0", "0-30", "31-60", "61-90", "90+"),
extend = TRUE, drop = FALSE)) %>%
# делаем сводку
group_by(tag) %>%
summarise(amount = sum(amount)) %>%
mutate_at("tag", as.character)
}
# Устанавливаем окно наблюдения
df <- seq.Date(as.Date("2021-04-01"), as.Date("2021-04-30"), by = "1 day") %>%
tibble(date = ., tbl = purrr::map(., calcDebt)) %>%
unnest(tbl)
# строим график
gp <- ggplot(df, aes(date, amount, colour = tag)) +
geom_point(alpha = 0.5, size = 3) +
geom_line() +
ggthemes::scale_colour_tableau("Tableau 10") +
theme_minimal()
gp
IS
IS