dplyr:计算产品补货天数

dplyr: calculate the days for product replenishment

我正在处理一个数据集,我需要在其中计算零售店补货所需的时间,这里是数据集的最简单形式的快速视图:

Date <- c("2019-1-1","2019-1-2","2019-1-3","2019-1-4","2019-1-5","2019-1-6","2019-1-7","2019-1-8")
Product <- rep("Product A",8)
Net_Available_Qty <- c(-2,-2,10,8,-5,-6,-7,0)
sample_df <- data.frame(Date,Product,Net_Available_Qty)

当Net_Available_Qty变为负数时,表示缺货。当它变回 0 或正数量时,表示供应已经恢复。我需要计算的是从我们第一次看到短缺到恢复短缺之间的天数。在这种情况下,第一次缺货需要2天才能恢复,第二次缺货需要3天才能恢复。

欢迎提供 tidyverse 解决方案。

我希望其他人找到更简洁的解决方案。但这会产生 diffDate ,它指定与负转 positive/zero.

的日期差异
sample_df %>%
  mutate(sign = ifelse(Net_Available_Qty > 0, "pos", ifelse(Net_Available_Qty < 0, "neg", "zero")),
         sign_lag = lag(sign, default = sign[1]),       # get previous value (exception in the first place)
         change = ifelse(sign != sign_lag, 1 , 0),      # check if there's a change
         sequence=sequence(rle(as.character(sign))$lengths)) %>%
  group_by(sequence) %>%
  mutate(diffDate = as.numeric(difftime(Date, lag(Date,1))),
         diffDate=ifelse(Net_Available_Qty <0, NA, ifelse((sign=='pos'| sign=='zero') & sequence==1, diffDate, NA))) %>% 
  ungroup() %>%
  select(Date, Product, Net_Available_Qty, diffDate)

@Schilker 使用 rle 有一个好主意。我在他的回答的基础上提供了一个略短的版本,包括使用 cumsum

Date <- c("2019-1-1","2019-1-2","2019-1-3","2019-1-4","2019-1-5","2019-1-6","2019-1-7","2019-1-8")
Product <- rep("Product A",8)
Net_Available_Qty <- c(-2,-2,10,8,-5,-6,-7,0)
sample_df <- data.frame(Date,Product,Net_Available_Qty)

library(tidyverse)

sample_df %>%
  mutate(
    diffDate = c(1, diff(as.Date(Date))),
    sequence = sequence(rle(Net_Available_Qty >= 0)$lengths),
    group = cumsum(c(TRUE, diff(sequence)) != 1L)
  ) %>%
  group_by(group) %>%
  mutate(n_days = max(cumsum(diffDate)))
#> # A tibble: 8 x 7
#> # Groups:   group [4]
#>   Date     Product   Net_Available_Qty diffDate sequence group n_days
#>   <fct>    <fct>                 <dbl>    <dbl>    <int> <int>  <dbl>
#> 1 2019-1-1 Product A                -2        1        1     0      2
#> 2 2019-1-2 Product A                -2        1        2     0      2
#> 3 2019-1-3 Product A                10        1        1     1      2
#> 4 2019-1-4 Product A                 8        1        2     1      2
#> 5 2019-1-5 Product A                -5        1        1     2      3
#> 6 2019-1-6 Product A                -6        1        2     2      3
#> 7 2019-1-7 Product A                -7        1        3     2      3
#> 8 2019-1-8 Product A                 0        1        1     3      1

reprex package (v0.3.0)

于 2020-02-23 创建