我有一个包含两列的数据框:业务和日期。对于此示例,如果某家企业在90天内有两次发货,则将其视为“有效”。 df未分组,因此可以有重复的行。
因此,数据如下所示:
Business Date
YUV 6/1/17
TRX 6/1/17
YUV 6/5/17
MON 6/5/17
TRX 10/10/17
TRX 10/10/17
TRX 11/5/17
在此示例中,将以开始日期6/1/17和激活日期6/1/17激活YUV。
TRX的装运时间为6/1/17,但是下一个要等到10/10/17才过去了90天。碰巧的是,它在10/10/17进行了多次装运,因此它被激活,开始日期为10/10/17,结束日期为10/10/17。我还想跟踪最近的发货和第一次发货以获取将来的指标,并将其放在激活的业务的单独数据框中,如下所示:
Business Min_Date Max_Date Act_Beg Act_End
YUV 6/1/17 6/5/17 6/1/17 6/5/17
TRX 6/1/17 11/5/17 10/10/17 10/10/17
到目前为止,我刚刚制作了一个空数据框:
Business_Active <- data.frame(Business = character(),
Min_Date = as.Date(character()),
Max_Date = as.Date(character()),
Active_Beg = as.Date(character()),
Active_End = as.Date(character()))
但是,我并不擅长for循环来介绍如何创建它,因此它会扫描“业务”列,对90天之间的所有实例进行计数,确定它已被激活,然后采用90天周期的开始, 90天期限的末尾以及首次发货日期和最近发货日期。
答案 0 :(得分:1)
带有data.table:
library(data.table)
首先生成示例数据
dt <- data.table(
business = c("YUV", "TRX", "YUV", "MON", "TRX", "TRX", "TRX"),
date = as.Date(c("06-01-17", "06-01-17", "06-05-17", "06-05-17", "10-10-17", "10-10-17", "11-05-17"))
)
以下是确定最大日期和最大日期的方法:
dt[ , min_date := min(date), by=business]
dt[ , max_date := max(date), by=business]
激活开始/结束需要几个步骤:
# get last date and next date for each transaction
dt[ , lastdate := shift(date, type="lag"), by=business]
dt[ , nextdate := shift(date, type="lead"), by=business]
# get number of days since last and next transactions
dt[ , days_since_last := date - lastdate]
dt[ , days_until_next := nextdate - date]
# flag if the transaction is an activation start/end
dt[ , activation_start := is.na(days_since_last) | days_since_last > 90]
dt[ , activation_end := days_since_last < 90 & shift(activation_start == TRUE)]
dt[is.na(activation_end), activation_end := FALSE]
激活结束后,Activated标志就很简单了:
# flag for whether activated
dt[ , activated := cumsum(activation_end) > 0, by=business]