首页 > 解决方案 > 通过 id 识别事件之前的日期

问题描述

我有一个数据集,我想在其中通过 ID 确定是否在事件(事件 = 1)之前发送了邀请(事件 = 0)。如果邀请在同一天或邀请(日期)至多在活动开始前 14 周,则视为已发送邀请。当事件发生时,此过程将重置。

这是我的数据框的示例:

   ID       Date Event
1   1 2017-01-01     0
2   1 2017-01-02     0
3   1 2017-01-03     0
4   1 2017-01-04     1
5   4 2017-01-03     1
6   4 2017-01-03     0
7   4 2017-01-06     1
8   4 2017-01-04     0
9   4 2017-01-05     0
10  5 2017-02-01     0
11  5 2018-01-02     1
12  7 2018-01-03     1

这是我想要的结果:

   ID       Date Event Sent
1   1 2017-01-01     0    0
2   1 2017-01-02     0    0
3   1 2017-01-03     0    0
4   1 2017-01-04     1    1
5   4 2017-01-03     1    1
6   4 2017-01-03     0    0
7   4 2017-01-06     1    1
8   4 2017-01-04     0    0
9   4 2017-01-05     0    0
10  5 2017-02-01     0    0
11  5 2018-01-02     1    0
12  7 2018-01-03     1    0

初始数据框:

df <- data.frame(ID = c(rep("1", 4), rep("4", 5), c("5", "5"), "7"), Date = c(seq(as.Date('2017-01-01'), as.Date('2017-01-4'), by = 'days'), c(as.Date('2017-01-3'), as.Date('2017-01-3')), as.Date('2017-01-06'), as.Date('2017-01-4'), as.Date('2017-01-5'), c(as.Date("2017-02-01"), as.Date('2018-01-02'), as.Date('2018-01-03'))), Event = c(0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1))

结果数据框:

result_df <-  data.frame(ID = c(rep("1", 4), rep("4", 5), c("5", "5"), "7"), Date = c(seq(as.Date('2017-01-01'), as.Date('2017-01-4'), by = 'days'), c(as.Date('2017-01-3'), as.Date('2017-01-3')), as.Date('2017-01-06'), as.Date('2017-01-4'), as.Date('2017-01-5'), c(as.Date("2017-02-01"), as.Date('2018-01-02'), as.Date('2018-01-03'))), Event = c(0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1), Sent = c(0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0))

标签: rdate

解决方案


使用的选项data.table

library(data.table)
setDT(df)[, c("weeks7ago", "Sent") := .(Date - 14 * 7, 0L)]
df[Event==1L, Sent := 
    df[Event==0L][.SD, on=.(ID, Date>=weeks7ago), by=.EACHI, .N>0L]$V1]

输出:

    ID       Date Event  weeks7ago Sent
 1:  1 2017-01-01     0 2016-09-25    0
 2:  1 2017-01-02     0 2016-09-26    0
 3:  1 2017-01-03     0 2016-09-27    0
 4:  1 2017-01-04     1 2016-09-28    1
 5:  4 2017-01-03     1 2016-09-27    1
 6:  4 2017-01-03     0 2016-09-27    0
 7:  4 2017-01-06     1 2016-09-30    1
 8:  4 2017-01-04     0 2016-09-28    0
 9:  4 2017-01-05     0 2016-09-29    0
10:  5 2017-02-01     0 2016-10-26    0
11:  5 2018-01-02     1 2017-09-26    0
12:  7 2018-01-03     1 2017-09-27    0

非常感谢您发布代码来创建数据,这样可以节省我们的时间。


推荐阅读