如何在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
相关产品推荐
相关产品推荐

