如何在 R 中的 data.table 中使用具有累积值的移位计算
How to use a shift calculation with a cumulative value in a data.table in R
我有一个 data.table 具有以下布局
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,0,0,0,0,0,0,0,0,0,0,0))
股票价值应使用以下公式计算为累计值:
If Stock (previous row) minus Demand (current row) is less or equal
than the threshold, than update the current cell in Stock with the
value in "Upto". Else update the value of stock (current row) with stock (previous row) minus demand (current row).
然后程序应该重新开始。结果应如下所示:
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,100,95,95,45,35,25,100,90,40,100,40))
Threshold Upto Demand Stock
1: 20 100 0 100
2: 20 100 0 100
3: 20 100 5 95
4: 20 100 0 95
5: 20 100 50 45
6: 20 100 10 35
7: 20 100 10 25
8: 20 100 10 100
9: 20 100 10 90
10: 20 100 50 40
11: 20 100 20 100
12: 20 100 60 40
我所做的如下:
TestData[, Stock:= ifelse(cumsum(shift(Stock, 0, type="lead") - Demand) <= Threshold,
Upto,
cumsum(shift(Stock, 0, type="lead") - Demand))]
但在第一次更新后计算停止,每次平铺结束时显示 100。库存中的第一个值是我手动设置的初始值。谢谢!
如果您可以接受循环解决方案。我不认为这对 dplyr(或 data.table)可行,但我希望有人能证明我错了。
for (i in 2:nrow(TestData)) {
# If stock - demand <= threshold, restock
if ((TestData[i-1, "Stock"] - TestData[i, "Demand"]) <= TestData[i, "Threshold"])
{
TestData[i, "Stock"] <- TestData[i-1, "Upto"]
}
# Else update stock with stock - demand
else
{
TestData[i, "Stock"] <- TestData[i-1, "Stock"] - TestData[i, "Demand"]
}
}
是一个棘手的问题。用do-while原则做的:
upVal = 100
threshVal = 20
cumVals <- TestData$Demand
cumMaster <- cumsum(cumVals)
repeat{
IND <- cumMaster>=upVal-threshVal
cumVals[min(which(IND == TRUE))] <- 0
cumMaster[IND] <- cumsum(cumVals[IND])
if(all(cumMaster<upVal-threshVal)){
break
}
}
TestData$Stock <- 100 - cumMaster
结果
TestData$Stock
这里有一个 data.table
解决方案。创新点在 by
组。请执行 post 此解决方案失败的任何边界情况。
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,0,0,0,0,0,0,0,0,0,0,0))
#to see by grouping
#TestData[,trunc(cumsum(Demand)/(Threshold - Upto))]
TestData[, Stock2 := c(Upto[1], Upto[1] - cumsum(Demand[-1])),
by=trunc(cumsum(Demand)/(Threshold - Upto))]
TestData
我有一个 data.table 具有以下布局
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,0,0,0,0,0,0,0,0,0,0,0))
股票价值应使用以下公式计算为累计值:
If Stock (previous row) minus Demand (current row) is less or equal than the threshold, than update the current cell in Stock with the value in "Upto". Else update the value of stock (current row) with stock (previous row) minus demand (current row).
然后程序应该重新开始。结果应如下所示:
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,100,95,95,45,35,25,100,90,40,100,40))
Threshold Upto Demand Stock
1: 20 100 0 100
2: 20 100 0 100
3: 20 100 5 95
4: 20 100 0 95
5: 20 100 50 45
6: 20 100 10 35
7: 20 100 10 25
8: 20 100 10 100
9: 20 100 10 90
10: 20 100 50 40
11: 20 100 20 100
12: 20 100 60 40
我所做的如下:
TestData[, Stock:= ifelse(cumsum(shift(Stock, 0, type="lead") - Demand) <= Threshold,
Upto,
cumsum(shift(Stock, 0, type="lead") - Demand))]
但在第一次更新后计算停止,每次平铺结束时显示 100。库存中的第一个值是我手动设置的初始值。谢谢!
如果您可以接受循环解决方案。我不认为这对 dplyr(或 data.table)可行,但我希望有人能证明我错了。
for (i in 2:nrow(TestData)) {
# If stock - demand <= threshold, restock
if ((TestData[i-1, "Stock"] - TestData[i, "Demand"]) <= TestData[i, "Threshold"])
{
TestData[i, "Stock"] <- TestData[i-1, "Upto"]
}
# Else update stock with stock - demand
else
{
TestData[i, "Stock"] <- TestData[i-1, "Stock"] - TestData[i, "Demand"]
}
}
是一个棘手的问题。用do-while原则做的:
upVal = 100
threshVal = 20
cumVals <- TestData$Demand
cumMaster <- cumsum(cumVals)
repeat{
IND <- cumMaster>=upVal-threshVal
cumVals[min(which(IND == TRUE))] <- 0
cumMaster[IND] <- cumsum(cumVals[IND])
if(all(cumMaster<upVal-threshVal)){
break
}
}
TestData$Stock <- 100 - cumMaster
结果
TestData$Stock
这里有一个 data.table
解决方案。创新点在 by
组。请执行 post 此解决方案失败的任何边界情况。
TestData <- data.table(Threshold = 20,
Upto = 100,
Demand = c(0,0,5,0,50,10,10,10,10,50,20,60),
Stock = c(100,0,0,0,0,0,0,0,0,0,0,0))
#to see by grouping
#TestData[,trunc(cumsum(Demand)/(Threshold - Upto))]
TestData[, Stock2 := c(Upto[1], Upto[1] - cumsum(Demand[-1])),
by=trunc(cumsum(Demand)/(Threshold - Upto))]
TestData