我不需要使用循环或应用,因为这需要非常有效:
对于那些了解LIFO或FIFO的人,这些是我试图使用的规则。基本上,请考虑以下库存矩阵:
基本上,给定库存矩阵“C”和一些“下降”,“qs”:
J=2
Tp=2
C = matrix(2,J,Tp)
rownam = as.character()
colnam = as.character()
for(j in 1:J){rownam = c(rownam,paste0('prod',j))}
for(j in 1:Tp){colnam = c(colnam,paste0('vint',j))}
rownames(C) = rownam
colnames(C) = colnam
C[1,1]=C[1,1]+1
C[2,1]=C[2,1]-1
> C
vint1 vint2
prod1 3 2
prod2 1 2
此库存矩阵表示有两种产品,每种产品都有两个年份。例如,我们有3个单位的1日龄产品1和2个单元的2日龄产品2.假设我们被告知减去3个单位的产品1。我们可以先从1年级或2年级开始。 LIFO将首先耗尽所有年份1,剩下0单位的1年份和2年份的2年份。先进先出先生将2个单位的2年份,并且因为有一个额外的单位要完成,所以最多可以从年份1,留下葡萄酒2和葡萄酒1的0。
下面,我将展示通常针对许多“下降”实施的此规则(例如,产品1的需求3和单元2中的4将是抽奖的一个示例)。
并且提取:
qs = rbind(
c(4, 1), c(4,1),
c(4, 1), c(1, 3),
c(3, 2), c(4, 1),
c(1, 2), c(2, 0),
c(2, 1), c(2, 3),
c(0, 3), c(2, 2))
> qs
[,1] [,2]
[1,] 4 1
[2,] 4 1
[3,] 4 1
[4,] 1 3
[5,] 3 2
[6,] 4 1
[7,] 1 2
[8,] 2 0
[9,] 2 1
[10,] 2 3
[11,] 0 3
[12,] 2 2
下降的每一行都是一个单独的模拟下降,将使用LIFO或FIFO应用于矩阵。 (LIFO意味着你在满足需求q时首先取消最新的年份(年份2)。而FIFO意味着你走另一条路。)
所以我跑:
Cmat = do.call(rbind, replicate(dim(qs)[1], C, simplify=FALSE)) #matrix
LIFO的输出应如下所示:
drawndown
vint1 vint2
prod1 1 0
prod2 1 1
prod1 1 0
prod2 1 1
prod1 1 0
prod2 1 1
prod1 3 1
prod2 0 0
...
答案 0 :(得分:1)
以下是您可以尝试使用data.table
的矢量化方法:
library(data.table)
draw_value <- as.vector(t(qs)) # flatten the draw down matrix as a vector
CmatDT <- data.table(Cmat, keep.rownames = T) # convert the Cmat to data.table
CmatDT[, `:=` (vint1 = ifelse(vint2 >= draw_value, vint1, vint1 + vint2 - draw_value),
vint2 = ifelse(vint2 >= draw_value, vint2 - draw_value, 0))]
# mutate the vint1 and vint2 columns based on if vint2 contains enough product for the draw down.
CmatDT
# rn vint1 vint2
# 1: prod1 1 0
# 2: prod2 1 1
# 3: prod1 1 0
# 4: prod2 1 1
# 5: prod1 1 0
# 6: prod2 1 1
# 7: prod1 3 1
# 8: prod2 0 0
# ...
更新:使用data.table
的更通用的解决方案很长,但主要是准备处理数据:
构建一个函数来从向量中减去一个数字,这将耗尽第一个元素,然后是第二个元素,直到数量为零:
minus <- function(vec, amount) {
if(vec[1] >= amount) c(vec[1] - amount, vec[-1])
else c(0, minus(vec[-1], amount - vec[1]))
}
数据准备:重塑下拉矩阵和库存,将它们绑定在一起进行进一步处理
qsDT <- setNames(data.table(qs, keep.rownames = T), c("DrawId", "Prod1", "Prod2"))
longQs <- melt(qsDT, id.vars = "DrawId", value.name = "Draw", variable.name = "Product")[order(as.numeric(DrawId))]
longQsC <- melt(cbind(longQs, C), measure.vars = c("vint1", "vint2"), value.name = "Inventory", variable.name = "Vintage")[order(as.numeric(DrawId), Product, -Vintage)]
通过从每个Draw
和Draw
的广告资源中减去Product
值来创建新广告资源,并重新整理结果:
longQsC[, NewInventory := minus(Inventory, unique(Draw)), .(DrawId, Product)]
longQsC[, dcast(.SD, Product ~ Vintage, value.var = "NewInventory"), .(DrawId)]
# DrawId Product vint1 vint2
#1: 1 Prod1 1 0
#2: 1 Prod2 1 1
#3: 2 Prod1 1 0
#4: 2 Prod2 1 1
#5: 3 Prod1 1 0
#6: 3 Prod2 1 1
#7: 4 Prod1 3 1
#8: 4 Prod2 0 0
# ...