如何使用cumsum,但有条件,如果<0,则使用0 [英] How to use cumsum but with condition if <0 then use 0
问题描述
我在两件事上都遇到了问题,但条件性累加的问题更为重要(我想这没什么大不了的).我想从每行的总和中减去1,如果结果为< 0,则不要使用负数,但以后要使用0.
I am having problems on 2 things but the problem with conditional cumsum is more important (and I guess less trivial). I would like to subtract 1 from the cumsum each row and if the result is <0, then do not use the negative number, but use 0 henceforth.
(1)当< 0
时不使用和使用0的总和(2)仅在第二行起运行
(1) cumsum not taking and using 0 when <0
(2) operate only on 2nd row onwards
这是示例表:
a <- data.table(
id1 = c(1,1,1,1,1,1,1,1,1,1),
id2 = c(1,2,3,4,5,6,7,8,9,10),
date = c("2020-01-01","2020-01-02","2020-01-03","2020-01-04","2020-01-05", "2020-01-06","2020-01-07","2020-01-08","2020-01-09","2020-01-10"),
DISPENSED_DURATION = c(4,0,0,0,0,0,0,4,0,0)
)
这是预期的结果:
id1 id2 date DISPENSED_DURATION DISP_INVT
1: 1 1 2020-01-01 4 4
2: 1 2 2020-01-02 0 3
3: 1 3 2020-01-03 0 2
4: 1 4 2020-01-04 0 1
5: 1 5 2020-01-05 0 0
6: 1 6 2020-01-06 0 0
7: 1 7 2020-01-07 0 0
8: 1 8 2020-01-08 4 3
9: 1 9 2020-01-09 0 2
10: 1 10 2020-01-10 0 1
以下是当前尝试的代码并获得了结果:
Here is the current codes tried and results obtained:
a[, DISP_INVT := cumsum(DISPENSED_DURATION-1), id1]
id1 id2 date DISPENSED_DURATION DISP_INVT
1: 1 1 2020-01-01 4 3
2: 1 2 2020-01-02 0 2
3: 1 3 2020-01-03 0 1
4: 1 4 2020-01-04 0 0
5: 1 5 2020-01-05 0 -1
6: 1 6 2020-01-06 0 -2
7: 1 7 2020-01-07 0 -3
8: 1 8 2020-01-08 4 0
9: 1 9 2020-01-09 0 -1
10: 1 10 2020-01-10 0 -2
a[, DISP_INVT := ifelse(cumsum(DISPENSED_DURATION-1)<0,0,cumsum(DISPENSED_DURATION-1)), id1]
id1 id2 date DISPENSED_DURATION DISP_INVT
1: 1 1 2020-01-01 4 3
2: 1 2 2020-01-02 0 2
3: 1 3 2020-01-03 0 1
4: 1 4 2020-01-04 0 0
5: 1 5 2020-01-05 0 0
6: 1 6 2020-01-06 0 0
7: 1 7 2020-01-07 0 0
8: 1 8 2020-01-08 4 0
9: 1 9 2020-01-09 0 0
10: 1 10 2020-01-10 0 0
a[, DISP_INVT := cumsum(ifelse(DISPENSED_DURATION-1<0,0,DISPENSED_DURATION-1)), id1]
id1 id2 date DISPENSED_DURATION DISP_INVT
1: 1 1 2020-01-01 4 3
2: 1 2 2020-01-02 0 3
3: 1 3 2020-01-03 0 3
4: 1 4 2020-01-04 0 3
5: 1 5 2020-01-05 0 3
6: 1 6 2020-01-06 0 3
7: 1 7 2020-01-07 0 3
8: 1 8 2020-01-08 4 6
9: 1 9 2020-01-09 0 6
10: 1 10 2020-01-10 0 6
非常感谢!
推荐答案
您需要在此处进行归约/迭代计算,而不是累加/矢量,因为一行中的值取决于上一行的计算值.
You need a reducing/iterative calculation here instead of a cumulative/vector, because the value in one row depends on the calculated value of the previous.
a[, DISP_INVT := Reduce(function(prev,this) max(0, prev+this-1),
DISPENSED_DURATION, accumulate = TRUE)]
a
# id1 id2 date DISPENSED_DURATION DISP_INVT
# <num> <num> <char> <num> <num>
# 1: 1 1 2020-01-01 4 4
# 2: 1 2 2020-01-02 0 3
# 3: 1 3 2020-01-03 0 2
# 4: 1 4 2020-01-04 0 1
# 5: 1 5 2020-01-05 0 0
# 6: 1 6 2020-01-06 0 0
# 7: 1 7 2020-01-07 0 0
# 8: 1 8 2020-01-08 4 3
# 9: 1 9 2020-01-09 0 2
# 10: 1 10 2020-01-10 0 1
这篇关于如何使用cumsum,但有条件,如果<0,则使用0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!