根据日期时间标准对值进行分类

Classify values based on datetime criteria

我希望能够根据日期时间标准对 R 中的某些事件进行分类。我有两个数据集,第一个数据集有拨打酒店公司电话线的客户的日期时间和 ID,另一个数据集有同一家酒店的所有预订的日期时间和客户 ID。

企业专线:

CTEL <- tibble::tribble(
 ~ID,  ~DATE_CALL,
 "01",  "08-25-20021 18:21:28",
 "01",  "07-26-20021 18:11:06",
 "02", "09-26-20021 18:21:01",
 "02",  "10-27-20021 20:21:59",
 "03",   "08-20-20021 20:21:02",
 "03",   "09-30-20021 20:21:03",
 "04",  "09-29-20021 20:21:04",
 "05",  "05-25-20021 20:21:05"
)

预订:

BOOKINGS <- tibble::tribble(
 ~ID,        ~BOOKINGS,         ~DATE_OF_BOOKING,       
 "01",   "UI89D", "08-20-20021 18:21:28", 
 "02", "PL882", "07-29-20021 18:11:06",
 "03",   "1254SDD", "01-27-20021 20:21:02", 
 "03", "DODK5845", "11-20-20021 20:21:03",
 "03", "MHXVJ7854E", "08-29-20021 20:21:02", 
 "04",   "85IORZ", "09-30-20021 20:21:04", 
 "05", "ZUI89DM", "8-25-20021 21:21:05", 
)

我希望能够创建三个新变量。其中之一是 PRIOR?有两个值“YES”和“NO”,另一个叫做 AFTER?还有两个值“YES”和“ONE”。最后一位是预约人数RESERV_NUM

分类规则:PRIOR?

如果客户使用日期时间 A 进行预订 X 我想知道此人是否在最近在此预订前 30 天 A,如果事实证明这是真的,那么让 PRIOR?为“是”否则为“否”

分类规则:AFTER?

如果客户预订了A with datetime X 我想知道这个人是否在接下来的时间里打过电话预订 A 3 天后,如果事实证明是真的,那么让 AFTER?为“是”否则为“否”

分类规则:RESERV_NUM

如果客户进行了预订 A,然后进行了预订 B,之后又进行了预订 C 如果预订“x”是他们的第一个、第二个、第三个等等,我希望能够按客户的预订分配...为了说明这一点是:

ID BOOKINGS RESERV_NUM
001 A 1
001 B 2
001 C 3

所需输出示例

ID:003 所需的输出示例为:

ID BOOKINGS RESERV_NUM PRIOR? AFTER?
001 1254SDD 1 NO NO
001 DODK5845 3 NO NO
001 MHXVJ7854E 2 YES NO

这是正确的,因为对于 MHXVJ7854E 的预订日期,我们有预订日期前 30 天的通话记录,并且在预订后的接下来 3 天内也没有通话记录。

我尝试了什么?

这个问题的关键是识别提取每次预订的日期,然后提取预订日期之前的电话线路上的最新记录以及预订日期之后3天的线路上的最新记录。

所以我首先加入这两个数据集,并按预订和通话日期的时间顺序对日期进行排序,我可以轻松地选择最新的预订日期和最晚的通话日期,但是,当它出现时我迷路了这些天来 selecting 知道“参考”应该是预订日期也许我可以用这个插图来解释我的追求:

<-------------------------- Booking/Reservation_Date--------------------->
        30 days after                                     3 days later


为了解决这个问题,我创建了两个不同的数据集,一个带有过滤器,这样电话线记录中的所有日期时间都小于预订日期,然后我 select 最新的一个..另一个数据集将通过 booking reservation 记录每次预订后的通话记录......我稍后会 select 最新的通话并比较它是否在“预订后的未来 3 天内”.. 然后我将不得不再次加入这两个数据集......但是这个过程虽然它给出了正确的结果但它可能有点混乱和冗长..我不知道你是否有才华,聪明的人可以指导我使用更完善的解决方案。

另一件事是我不知道如何将 RESERV_NUM 分配给每个 BOOKING..R 上有可以做到这一点的功能吗?

非常感谢您

RESERV_NUM,因为客户今天打电话订下个月,明天打电话订这个月,所以我就直接用DATE_OF_BOOKINGBOOKINGS.

# I have convert the date to 2021 rather than 20021, which will cause error.
CTEL <- tibble::tribble(
   ~ID,  ~DATE_CALL,
   "01",  "08-25-2021 18:21:28",
   "01",  "07-26-2021 18:11:06",
   "02", "09-26-2021 18:21:01",
   "02",  "10-27-2021 20:21:59",
   "03",   "08-20-2021 20:21:02",
   "03",   "09-30-2021 20:21:03",
   "04",  "09-29-2021 20:21:04",
   "05",  "05-25-2021 20:21:05"
 )
 
 BOOKINGS <- tibble::tribble(
   ~ID,        ~BOOKINGS,         ~DATE_OF_BOOKING,       
   "01",   "UI89D", "08-20-2021 18:21:28", 
   "02", "PL882", "07-29-2021 18:11:06",
   "03",   "1254SDD", "01-27-2021 20:21:02", 
   "03", "DODK5845", "11-20-2021 20:21:03",
   "03", "MHXVJ7854E", "08-29-2021 20:21:02", 
   "04",   "85IORZ", "09-30-2021 20:21:04", 
   "05", "ZUI89DM", "08-25-2021 21:21:05", 
 ) 
 
 
 lapply(unique(BOOKINGS$ID), function(x){
   bookings <- dplyr::filter(BOOKINGS, ID == x)
   ctel <- dplyr::filter(CTEL, ID == x)
   
   bookings$DATE_OF_BOOKING <- strptime(bookings$DATE_OF_BOOKING, format = "%m-%d-%Y %T")
   ctel$DATE_CALL <- strptime(ctel$DATE_CALL, format = "%m-%d-%Y %T")
   pa <- plyr::rbind.fill(lapply(bookings$DATE_OF_BOOKING, function(y){
     cond <- sum(ctel$DATE_CALL <= y & ctel$DATE_CALL >= y - lubridate::ddays(30)) > 0
     prior <- ifelse(cond, "YES", "NO")
     cond <- sum(ctel$DATE_CALL >= y & ctel$DATE_CALL <= y + lubridate::ddays(3)) > 0
     after <- ifelse(cond, "YES", "NO")
     return(as.data.frame(list(prior = prior, after = after)))
   }))
   
   output <- cbind(bookings, pa)
   output <- output[order(output$DATE_OF_BOOKING), ]
   output$RESERV_NUM <- c(1:nrow(output))
   output <- output[, c("ID", "BOOKINGS", "RESERV_NUM", "prior", "after")]
   names(output) <- c("ID", "BOOKINGS", "RESERV_NUM", "PRIOR?", "AFTER?")
   rownames(output) <- NULL
   
   return(output)
 })

## [[1]]
##   ID BOOKINGS RESERV_NUM PRIOR? AFTER?
## 1 01    UI89D          1    YES     NO
##
## [[2]]
##   ID BOOKINGS RESERV_NUM PRIOR? AFTER?
## 1 02    PL882          1     NO     NO
##
## [[3]]
##   ID   BOOKINGS RESERV_NUM PRIOR? AFTER?
## 1 03    1254SDD          1     NO     NO
## 2 03 MHXVJ7854E          2    YES     NO    # Notice that customer 3 did not call back within three days
## 3 03   DODK5845          3     NO     NO
##
## [[4]]
##  ID BOOKINGS RESERV_NUM PRIOR? AFTER?
## 1 04   85IORZ          1    YES     NO
##
## [[5]]
##  ID BOOKINGS RESERV_NUM PRIOR? AFTER?
## 1 05  ZUI89DM          1     NO     NO