如何在R

时间:2017-04-12 14:49:26

标签: r data.table shift

我有一个带有以下布局的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))

股票价值应计算为累计值,公式为:

  

如果股票(前一行)减去需求(当前行)小于或等于   超过阈值,比用库存更新库存中的当前单元格   “Upto”中的值。否则,使用库存(上一行)减去需求(当前行)更新库存(当前行)的值。

然后程序应该重新开始。结果应如下所示:

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次结束。库存中的第一个值是我手动设置的初始值。谢谢!

3 个答案:

答案 0 :(得分:4)

这是一个data.table解决方案。创新是在by分组。请发布此解决方案失败的任何边界情况。

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

答案 1 :(得分:2)

如果您能使用循环解决方案。我不认为这对dplyr(或data.table)是可行的,但我希望有人能证明我错了。

{{1}}

答案 2 :(得分:2)

是一个棘手的问题。是否采用了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