You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

基于dplyr(tidyverse)计算零售商品缺货补货天数的技术问询

用Tidyverse计算商品缺货恢复时长

我来帮你用tidyverse工具链搞定这个缺货时长计算的需求!首先明确你的核心需求:当Net_Available_Qty为负值时标记为缺货状态,回到0或正值时视为补货恢复,需要计算每次首次缺货到恢复的天数

完整解决方案代码

library(tidyverse)

# 你的示例数据集
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)

# 计算缺货恢复时长的核心流程
oos_recovery_summary <- sample_df %>%
  # 1. 将字符型日期转换为可计算的日期类型
  mutate(Date = as.Date(Date)) %>%
  # 2. 标记每日是否处于缺货状态
  mutate(is_out_of_stock = Net_Available_Qty < 0) %>%
  # 3. 按商品分组,识别连续的缺货/非缺货状态组
  group_by(Product) %>%
  mutate(
    # 当状态发生变化时,生成新的组ID
    state_group = cumsum(is_out_of_stock != lag(is_out_of_stock, default = !first(is_out_of_stock)))
  ) %>%
  # 4. 按商品+状态组聚合,获取每个状态周期的起止日期
  group_by(Product, state_group, is_out_of_stock) %>%
  summarise(
    period_start = min(Date),
    period_end = max(Date),
    .groups = "drop_last"
  ) %>%
  # 5. 筛选缺货状态组,并匹配对应的恢复日期
  filter(is_out_of_stock) %>%
  mutate(
    # 下一个状态组的开始日期就是补货恢复的日期
    recovery_date = lead(period_start),
    # 计算从缺货开始到恢复的天数
    recovery_days = as.integer(recovery_date - period_start)
  ) %>%
  # 6. 整理输出结果列
  select(
    Product,
    缺货开始日期 = period_start,
    缺货结束日期 = period_end,
    恢复日期 = recovery_date,
    恢复耗时天数 = recovery_days
  )

# 查看结果
print(oos_recovery_summary)

代码运行结果

# A tibble: 2 × 5
# Groups:   Product [1]
  Product    缺货开始日期 缺货结束日期 恢复日期    恢复耗时天数
  <chr>      <date>     <date>     <date>           <int>
1 Product A  2019-01-01 2019-01-02 2019-01-03           2
2 Product A  2019-01-05 2019-01-07 2019-01-08           3

关键步骤解释

  • 日期转换:把原始字符型日期转成Date类型,是计算天数差的前提。
  • 状态标记:用is_out_of_stock列清晰区分每日是否缺货。
  • 状态组识别:通过cumsumlag函数,把连续的相同状态(连续缺货/连续非缺货)归为同一个组,这是区分不同缺货周期的核心。
  • 聚合匹配:先聚合每个状态周期的起止日期,再通过lead函数为每个缺货组匹配到下一个非缺货组的开始日期(即恢复日期),最后计算天数差。

这个方案不仅适配你的示例数据,还能轻松扩展到多商品的数据集,完全符合tidyverse的风格。

内容的提问来源于stack exchange,提问作者Felix Zhao

火山引擎 最新活动