我有一个有关简单订单处理系统的数据,其中包含每日已完成和已完成订单的数量。以下是一些简化的数据:
Date <- seq(as.Date('2018-01-01'), as.Date('2018-01-10'), by = "day")
In <- c(10, 6, 9, 5, 8, 4, 7, 12, 9, 7)
Out <- c(4, 7, 3, 8, 5, 6, 3, 9, 7, 4)
df <- data.frame(Date, In, Out)
对于我要计算的每个日期:
订单处理遵循“先进先出”规则。我们假设系统从上一个期间的10个待处理订单开始。然后,使用dplyr可以很容易地计算出正在进行的工作WIP
:
df <- df %>% mutate(In.cumul = 10 + cumsum(In),
Out.cumul = cumsum(Out),
WIP = In.cumul - Out.cumul)
此输出的引导:
Date In Out In.cumul Out.cumul WIP
1 2018-01-01 10 4 20 4 16
2 2018-01-02 6 7 26 11 15
3 2018-01-03 9 3 35 14 21
4 2018-01-04 5 8 40 22 18
5 2018-01-05 8 5 48 27 21
6 2018-01-06 4 6 52 33 19
7 2018-01-07 7 3 59 36 23
8 2018-01-08 12 9 71 45 26
9 2018-01-09 9 7 80 52 28
10 2018-01-10 7 4 87 56 31
我的问题是如何实施以上第二部分。计算如下:对于Out.cumul
的每个值,查询In_cumul
首次达到该值(或刚好高于该值)的日期。
我想避免For
循环或创建定制函数,而更喜欢dplyr中的矢量化操作。 dplyr中的lag()
和lead()
最接近,但是偏移量在这里未知,必须根据数据进行计算。因此,这将是某种反向lag()
函数。
预期输出是这样:
Date In Out In.cumul Out.cumul WIP Oldest
1 2018-01-01 10 4 20 4 16 2018-01-01
2 2018-01-02 6 7 26 11 15 2018-01-01
3 2018-01-03 9 3 35 14 21 2018-01-01
4 2018-01-04 5 8 40 22 18 2018-01-02
5 2018-01-05 8 5 48 27 21 2018-01-03
6 2018-01-06 4 6 52 33 19 2018-01-03
7 2018-01-07 7 3 59 36 23 2018-01-04
8 2018-01-08 12 9 71 45 26 2018-01-05
9 2018-01-09 9 7 80 52 28 2018-01-06
10 2018-01-10 7 4 87 56 31 2018-01-07
非常感谢使用dplyr的优雅解决方案。
答案 0 :(得分:1)
我们可以使用map
中的purrr
遍历每个Out.Cuml
并找出越过In.cumul
的最近日期
library(tidyverse)
df %>%
mutate(Oldest = Date[as.integer(map(Out.cumul,
function(x) which.max(In.cumul - x >= 0)))])
# Date In Out In.cumul Out.cumul WIP Oldest
#1 2018-01-01 10 4 20 4 16 2018-01-01
#2 2018-01-02 6 7 26 11 15 2018-01-01
#3 2018-01-03 9 3 35 14 21 2018-01-01
#4 2018-01-04 5 8 40 22 18 2018-01-02
#5 2018-01-05 8 5 48 27 21 2018-01-03
#6 2018-01-06 4 6 52 33 19 2018-01-03
#7 2018-01-07 7 3 59 36 23 2018-01-04
#8 2018-01-08 12 9 71 45 26 2018-01-05
#9 2018-01-09 9 7 80 52 28 2018-01-06
#10 2018-01-10 7 4 87 56 31 2018-01-07
在基数R中,我们可以使用sapply
df$Oldest <- df$Date[sapply(df$Out.cumul, function(x) which.max(df$In.cumul - x >= 0))]
答案 1 :(得分:1)
使用findInterval
df %>%
mutate(Oldest = Date[findInterval(Out.cumul, In.cumul, left.open = TRUE) + 1])
给予:
Date In Out In.cumul Out.cumul WIP Oldest
1 2018-01-01 10 4 20 4 16 2018-01-01
2 2018-01-02 6 7 26 11 15 2018-01-01
3 2018-01-03 9 3 35 14 21 2018-01-01
4 2018-01-04 5 8 40 22 18 2018-01-02
5 2018-01-05 8 5 48 27 21 2018-01-03
6 2018-01-06 4 6 52 33 19 2018-01-03
7 2018-01-07 7 3 59 36 23 2018-01-04
8 2018-01-08 12 9 71 45 26 2018-01-05
9 2018-01-09 9 7 80 52 28 2018-01-06
10 2018-01-10 7 4 87 56 31 2018-01-07