如何编写在R中创建日历的有效代码?

时间:2018-09-05 14:45:34

标签: r performance dplyr data.table

我的目标是编写更有效的代码,以创建一个日历,以将经销商的客户分配到不同的日期,以便:

  1. 整天每天至少有min个客户,(min取决于经销商)
  2. 整天每天最多有max个客户,(max取决于经销商)
  3. 每当客户转移到另一天时,都应该将其转移到最近的一天(不要理会领带-如果距离相同,则前1天或后1天相同)

示例:

dealer_id  <- rep(c("ABC123","DEF234","GHJ456"), each = 4)
date       <- as.Date(rep(c("2018-01-01", "2018-01-02", "2018-01-03", "2018-01-04"), times = 3))
cust_pos_1 <- c("MCA1", "MCA2", "MCA3", "MCA4", "MCA5", "MCA6", NA, NA, "MCA9", "MCA10", "MCA11", "MCA12")
cust_pos_2 <- c("MCB1", "MCB2", NA, NA, "MCB5", NA, NA, NA, "MCB9", NA, "MCB11", NA)
cust_pos_3 <- c("MCC1", "MCC2", NA, NA, NA, NA, NA, NA, "MCC9", NA, NA, NA)

df         <- data.frame(dealer_id, date, cust_pos_1, cust_pos_2, cust_pos_3)

settings   <- data.frame(dealer_id = c("ABC123","DEF234","GHJ456"), min_daily = c(2, 0, 1), max_daily = c(3, 1, 2))

为我们提供输入数据和经销商设置:

dealer_id date       cust_pos_1 cust_pos_2 cust_pos_3
ABC123    2018-01-01 MCA1       MCB1       MCC1
ABC123    2018-01-02 MCA2       MCB2       MCC2
ABC123    2018-01-03 MCA3       NA         NA
ABC123    2018-01-04 MCA4       NA         NA
DEF234    2018-01-01 MCA5       MCB5       NA
DEF234    2018-01-02 MCA6       NA         NA
DEF234    2018-01-03 NA         NA         NA
DEF234    2018-01-04 NA         NA         NA
GHJ456    2018-01-01 MCA9       MCB9       MCC9
GHJ456    2018-01-02 MCA10      NA         NA
GHJ456    2018-01-03 MCA11      MCB11      NA
GHJ456    2018-01-04 MCA12      NA         NA

dealer_id min_daily max_daily
ABC123    2         3
DEF234    0         1
GHJ456    1         2

,代码运行后的输出数据应如下所示:

dealer_id date       cust_pos_1 cust_pos_2 cust_pos_3
ABC123    2018-01-01 MCA1       MCB1       NA
ABC123    2018-01-02 MCA2       MCB2       NA
ABC123    2018-01-03 MCA3       MCC1       NA
ABC123    2018-01-04 MCA4       MCC2       NA
DEF234    2018-01-01 MCA5       NA         NA
DEF234    2018-01-02 MCA6       NA         NA
DEF234    2018-01-03 MCB5       NA         NA
DEF234    2018-01-04 NA         NA         NA
GHJ456    2018-01-01 MCA9       MCB9       NA
GHJ456    2018-01-02 MCA10      MCC9       NA
GHJ456    2018-01-03 MCA11      MCB11      NA
GHJ456    2018-01-04 MCA12      NA         NA

由于设置-必须根据上述规则重新分配客户。

设置表也有一条规则! minmax之间的差异始终为1。

琐碎地说,有多种解决方法,因为我们不在乎客户是否在x天之前x天之后移动,这意味着我们可以有所不同(更好!)。 )解决方案。

现在。话虽这么说,但我已经使用一个需要花费很长时间才能运行的循环解决了这个问题(我的数据帧非常庞大-我必须为5年创建这个日历,并为150个拥有数百个客户的经销商创建日历)。

我的问题是:有没有办法使用dplyrdata.table或其他方法来使它运行得更快?

谢谢。

1 个答案:

答案 0 :(得分:2)

下面的代码将填充超出max_daily设置范围的客户可接受的单元格中的空白区域。但是,一个潜在的问题可能是该代码将客户重新安置在远离原始日期的地方。 提供的代码与dplyr管道运算符兼容,并且非常快捷。

df1[~df1.notnull()] = df2[df2.notnull()]