如何使用cumsum,但有条件,如果<0,则使用0 [英] How to use cumsum but with condition if &lt;0 then use 0

查看:58
本文介绍了如何使用cumsum,但有条件,如果<0,则使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆