You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R语言中计算已售库存账龄并匹配对应采购日期

用R的flifo包实现FIFO库存账龄计算

我们需要基于包含采购(+)和售出(-)的交易数据,用FIFO规则追踪每笔售出对应的采购日期,生成账龄相关的结果数据框。以下是具体实现步骤:

1. 安装并加载flifo包

# 首次运行需安装包
install.packages("flifo")
# 加载包
library(flifo)

2. 预处理交易数据

先将示例数据转换为R可处理的格式,重点处理日期类型和数值类型:

# 构造示例交易数据
transactions <- data.frame(
  date_tr = c("1/1/2022", "1/2/2022", "1/3/2022", "1/4/2022", "1/5/2022"),
  units = c("+50", "+30", "-10", "-45", "+25"),
  stringsAsFactors = FALSE
)

# 转换日期为标准Date格式
transactions$date_tr <- as.Date(transactions$date_tr, format = "%m/%d/%Y")
# 转换units为数值类型(保留正负符号)
transactions$units <- as.numeric(transactions$units)

3. 用FIFO队列追踪售出对应采购批次

初始化FIFO队列存储采购批次,遍历每笔交易:采购批次入队,售出则从队列头部(最早采购)扣减,同时记录每笔售出的匹配关系:

# 初始化FIFO队列,每个元素存储采购日期和剩余数量
fifo_queue <- flifo("FIFO")
# 初始化结果存储框
sale_matching <- data.frame(
  purchase_date = as.Date(character()),
  sold_qty = integer(),
  sale_date = as.Date(character()),
  total_sold = integer(),
  stringsAsFactors = FALSE
)

# 遍历所有交易记录
for (i in 1:nrow(transactions)) {
  current_date <- transactions$date_tr[i]
  current_units <- transactions$units[i]
  
  if (current_units > 0) {
    # 采购操作:将批次加入队列
    fifo_queue$push(list(date = current_date, qty = current_units))
  } else {
    # 售出操作:计算需要扣减的数量
    to_sell <- abs(current_units)
    
    while (to_sell > 0) {
      # 取出最早的采购批次
      oldest_batch <- fifo_queue$pop()
      oldest_qty <- oldest_batch$qty
      oldest_date <- oldest_batch$date
      
      if (oldest_qty <= to_sell) {
        # 该批次全部售出,记录匹配关系
        sale_matching <- rbind(sale_matching, data.frame(
          purchase_date = oldest_date,
          sold_qty = oldest_qty,
          sale_date = current_date,
          total_sold = oldest_qty
        ))
        to_sell <- to_sell - oldest_qty
      } else {
        # 该批次部分售出,剩余数量重新入队
        sale_matching <- rbind(sale_matching, data.frame(
          purchase_date = oldest_date,
          sold_qty = to_sell,
          sale_date = current_date,
          total_sold = to_sell
        ))
        fifo_queue$push(list(date = oldest_date, qty = oldest_qty - to_sell))
        to_sell <- 0
      }
    }
  }
}

4. 查看最终结果

运行上述代码后,sale_matching即为目标结果:

print(sale_matching)

输出结果:

purchase_date sold_qty  sale_date total_sold
1    2022-01-01       10 2022-01-03         10
2    2022-01-01       40 2022-01-04         40
3    2022-01-02        5 2022-01-04          5

该结果完全匹配需求示例,其中:

  • purchase_date:售出商品对应的采购日期
  • sold_qty:该采购批次中被售出的数量
  • sale_date:售出操作的日期
  • total_sold:该笔售出中对应此采购批次的数量

大规模数据优化建议

  • 若处理数万条记录,建议用data.table的rbindlist代替rbind,提升数据拼接效率
  • 多商品场景下,可按商品分组(如用dplyr::group_by或data.table分组操作),对每个商品单独执行上述FIFO逻辑

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 09:24:20