R编程遍历企业并确定他们是否在90天内发货

时间:2018-08-21 14:44:14

标签: r loops for-loop

我有一个包含两列的数据框:业务和日期。对于此示例,如果某家企业在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天期限的末尾以及首次发货日期和最近发货日期。

1 个答案:

答案 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]