基于R语言实现物料清单(BOM)递归累计成本计算
用R递归计算物料清单(BOM)的累计成本
首先明确BOM的数据结构,我们需要补充parent_id字段关联父物料与子物料(否则无法递归溯源子件),示例数据如下:
# 构造示例BOM数据框 bom <- data.frame( item_id = c("成品A", "组件B", "组件C", "原料D", "原料E", "原料F"), level = c(0, 1, 1, 2, 2, 2), parent_id = c(NA, "成品A", "成品A", "组件B", "组件B", "组件C"), quantity = c(1, 2, 1, 3, 1, 2), price = c(0, 0, 0, 5, 10, 8) )
接下来编写递归函数,核心逻辑:如果当前物料的price不为0,直接返回该价格;如果为0,则递归计算所有子物料的累计成本,乘以对应用量后求和,得到当前物料的最终成本:
get_final_price <- function(item_id, bom_data) { # 获取当前物料的行数据 current_item <- bom_data[bom_data$item_id == item_id, ] # 如果当前物料已有价格,直接返回 if (current_item$price != 0) { return(current_item$price) } # 找到当前物料的所有子物料 children <- bom_data[bom_data$parent_id == item_id, ] # 递归计算每个子物料的最终成本,乘以用量后求和 total_cost <- sum(children$quantity * sapply(children$item_id, get_final_price, bom_data = bom_data)) return(total_cost) }
现在可以调用函数计算任意物料的最终成本:
# 计算成品A的最终成本 get_final_price("成品A", bom) # 计算组件B的最终成本 get_final_price("组件B", bom)
如果需要给整个BOM数据框添加final_price列,可以用dplyr简化操作:
library(dplyr) bom <- bom %>% rowwise() %>% mutate(final_price = get_final_price(item_id, bom)) %>% ungroup()
注意事项
- 必须确保BOM无循环引用(比如物料A的子件是物料B,物料B的子件又包含物料A),否则递归会陷入无限循环
- 层级从n到0的结构不影响递归逻辑,只要父子关联正确,函数会自动溯源到最底层有价格的物料
内容的提问来源于stack exchange,提问作者LHA
相关产品推荐
相关产品推荐

