создание уникальной переменной на основе различий строк другой переменной с учетом групп - PullRequest
0 голосов
/ 10 июля 2019

Используя приведенные ниже данные, я хочу создать новый уникальный идентификатор клиента с учетом даты его контакта.Правило: каждые два дня я хочу, чтобы каждый клиент получал новый уникальный идентификатор клиента и сохранял его в следующей записи, если следующая дата контакта для того же клиента находится в течение следующих двух дней, если не назначить новый идентификатор этому же клиенту.

Я не мог пойти дальше, чем вычисление разницы дат.Исходный набор данных, с которым я работаю, больше;поэтому я предпочитаю решение для data.table, если это возможно.

library(data.table)
treshold <- 2
dt <- structure(list(customer_id = c('10','20','20','20','20','20','30','30','30','30','30','40','50','50'),
                      contact_date = as.Date(c("2019-01-05","2019-01-01","2019-01-01","2019-01-02",
                                               "2019-01-08","2019-01-09","2019-02-02","2019-02-05",
                                               "2019-02-05","2019-02-09","2019-02-12","2019-02-01",
                                               "2019-02-01","2019-02-05")),
                      desired_output = c(1,2,2,2,3,3,4,5,5,6,7,8,9,10)), 
                 class = "data.frame", 
                 row.names = 1:14)
setDT(dt)
setorder(dt, customer_id, contact_date)
dt[, date_diff_in_days:=contact_date - shift(contact_date, type = c("lag")), by=customer_id]
dt[, date_diff_in_days:=as.numeric(date_diff_in_days)]
dt

    customer_id contact_date desired_output date_diff_in_days
 1:          10   2019-01-05              1                NA
 2:          20   2019-01-01              2                NA
 3:          20   2019-01-01              2                 0
 4:          20   2019-01-02              2                 1
 5:          20   2019-01-08              3                 6
 6:          20   2019-01-09              3                 1
 7:          30   2019-02-02              4                NA
 8:          30   2019-02-05              5                 3
 9:          30   2019-02-05              5                 0
10:          30   2019-02-09              6                 4
11:          30   2019-02-12              7                 3
12:          40   2019-02-01              8                NA
13:          50   2019-02-01              9                NA
14:          50   2019-02-05             10                 4

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

Правило: каждые два дня я хочу, чтобы каждый клиент получал новый уникальный идентификатор клиента и сохранял его в следующей записи, если следующая дата контакта для того же клиента находится в течение следующих двух дней, если не назначен новый идентификатор для этот же клиент.

При создании нового идентификатора, если вы правильно настроили векторы by= для захвата правила, можно использовать автоматический счетчик .GRP:

thresh <- 2
dt[, g := .GRP, by=.(
  customer_id, 
  cumsum(contact_date - shift(contact_date, fill=first(contact_date)) > thresh)
)]

dt[, any(g != desired_output)]
# [1] FALSE

Я думаю, что приведенный выше код верен, поскольку он работает на примере, но вы можете проверить свои фактические данные (сравнивая результаты, например, с подходом Грегора).

2 голосов
/ 10 июля 2019

Мы используем cumsum для увеличения всякий раз, когда date_diff_in_days равно NA или когда превышен порог.

dt[, result := cumsum(is.na(date_diff_in_days) | date_diff_in_days > treshold)]
#     customer_id contact_date desired_output date_diff_in_days result
#  1:          10   2019-01-05              1                NA      1
#  2:          20   2019-01-01              2                NA      2
#  3:          20   2019-01-01              2                 0      2
#  4:          20   2019-01-02              2                 1      2
#  5:          20   2019-01-08              3                 6      3
#  6:          20   2019-01-09              3                 1      3
#  7:          30   2019-02-02              4                NA      4
#  8:          30   2019-02-05              5                 3      5
#  9:          30   2019-02-05              5                 0      5
# 10:          30   2019-02-09              6                 4      6
# 11:          30   2019-02-12              7                 3      7
# 12:          40   2019-02-01              8                NA      8
# 13:          50   2019-02-01              9                NA      9
# 14:          50   2019-02-05             10                 4     10
...