基于某些条件的累积金额

时间:2015-09-09 10:58:29

标签: r dplyr

这是我的数据框:

       X   Y  Date   Qty  CumSumA  CumSumB
    1  A   B   1/1     1        1        0
    2  A   A   1/1     2        3        2
    3  A   E   1/1     2        5        2
    4  B   A   1/1     1        1        1
    5  B   B   1/1     3        4        4
    6  B   C   1/1     2        6        4
    7  C   D   1/1     2        2        2
    8  C   E   1/1     4        6        2
    9  C   A   1/1     1        7        2
   10  A   C   1/2     2        2        0
   11  A   D   1/2     3        5        0
   12  A   E   1/2     2        7        0
   13  B   A   1/2     5        5        0
   14  B   B   1/2     1        6        1
   15  B   C   1/2     2        8        1
   16  C   D   1/2     2        2        4
   17  C   E   1/2     1        1        4
   18  C   A   1/2     3        4        4

我用

获得了CumSumA专栏
library(dplyr)
data <- data %>% 
        group_by(Date,X) %>% 
        mutate(CumSumA= cumsum(Qty)) 

如何获取CumSumB列,使其成为上述所有行的Qty的累积和,其中(a)具有相同的Date值,并且(b)相同的行{{1}列X中的值。

因此,例如,第16行的值为Y,值为X。我希望得到Date值为QtyY值为1/2的所有行的累计总和。所以这将是10行加15行,所以CumSumB是2 + 2 = 4。

注意X列和Y列有超过140个唯一变量。

1 个答案:

答案 0 :(得分:3)

此解决方案基于data.tableallow.cartesian=TRUE

的联接
require(data.table)
setDT(DT)

创建我们稍后将使用其data.table列的基础X

DT_X <- DT[,.(X,Y, Date, indx = .I)]
setkey(DT_X, Date, X)

删除X并在原始DT

中插入索引
DT[,`:=`(X=NULL, indy = .I)]
setkey(DT, Date, Y)

如果X = Yallow.cartesian=TRUE)加入数据。如果你好奇,请看DT_join。请参阅Why does X[Y] join of data.tables not allow a full outer join, or a left join?为什么这是一个加入

DT_join <- DT_X[DT, allow.cartesian=TRUE]

indy<=indx是一个标识符,只取&#34;&#34;以上所有行的总和。就像你说的那样。

DT_join[!is.na(Y), .(CumSumB=sum(Qty * (indy<=indx))), by=.(X,Y,Date)]

编辑(基于aosmith答案):代替by=.(X,Y,Date),也可以使用by=indx

结果:

    X Y Date CumSumB
 1: A B  1/1       0
 2: A A  1/1       2
 3: A E  1/1       2
 4: B A  1/1       1
 5: B B  1/1       4
 6: B C  1/1       4
 7: C D  1/1       2
 8: C E  1/1       2
 9: C A  1/1       2
10: A C  1/2       0
11: A D  1/2       0
12: A E  1/2       0
13: B A  1/2       0
14: B B  1/2       1
15: B C  1/2       1
16: C D  1/2       4
17: C E  1/2       4
18: C A  1/2       4