首页 > 解决方案 > R Programming 循环遍历企业并确定它们是否在 90 天内发货

问题描述

我有一个包含两列业务和日期的数据框。在此示例中,如果一家企业在 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

在此示例中,YUV 的激活日期为 2017 年 6 月 1 日,激活日期为 2017 年 6 月 1 日。

TRX 在 2017 年 6 月 1 日发货,但下一个要到 2017 年 10 月 10 日,90 天过去了。碰巧它在 2017 年 10 月 10 日有多次发货,所以它在 2017 年 10 月 10 日和 2017 年 10 月 10 日结束时激活。我还想跟踪最近的发货和第一次发货以获取未来的指标,并将其放在一个单独的激活业务数据框中,如下所示:

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 天期限以及第一个装运日期和最近装运日期。

标签: rloopsfor-loop

解决方案


使用数据表:

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]

一旦我们有了 Activation End,Activated 标志就很简单了:

# flag for whether activated
dt[ , activated := cumsum(activation_end) > 0, by=business]

推荐阅读