R 基于特定条件的累积总和

R 基于特定条件的累积总和,r,dplyr,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

这是我的数据框:

       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)) 
库(dplyr)
数据%
分组依据(日期,X)%>%
变异(累积量=累积量(数量))
如何获取CumSumB列,使其成为上面具有(a)相同
Date
值和(b)列
Y
中相同行
X
值的所有行的
Qty
的累计和

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


注意:X列和Y列有140多个唯一变量。

此解决方案基于
数据。表
和带有
allow.cartesian=TRUE的联接

require(data.table)
setDT(DT)
创建一个基本的
data.table
,其
X
列将在后面使用

DT_X <- DT[,.(X,Y, Date, indx = .I)]
setkey(DT_X, Date, X)
如果
X=Y
(使用
allow.cartesian=TRUE
)连接数据。如果您有兴趣,请查看
DT_join
。明白为什么这是一个连接吗

DT_join <- DT_X[DT, allow.cartesian=TRUE]
这里是一个基于dplyr的答案,使用与@0相同的逻辑。这将趋于缓慢,因为您有更多的组

首先,我将行号作为列添加到原始数据集中。将使用此方法为每个唯一行计算
CumSumB

library(dplyr)

dat = dat %>% mutate(row = row_number())
然后我将数据集连接到自身,将
X
连接到
Y
并按
Date
连接。为了避免许多添加了后缀的重复列,我只为联接的
x
数据集选择了一些列(即
left\u联接的第一个数据集)

我故意在两个数据集中保留了变量
row
,因此我最终得到了一个名为
row.x
的变量,该变量表示每个
x
值的原始行号,以及一个名为
row.y
的变量,该变量表示每个
y
值的原始行号

dat %>% 
    left_join(select(dat, X, Date, Y, row), ., by  = c("X" = "Y", "Date" = "Date"))
完成后,数据集只需按
row.x
分组,并在
row.x
小于或等于
row.y
的条件下计算
Qty
之和

dat %>% 
    left_join(select(dat, X, Date, Y, row), ., by  = c("X" = "Y", "Date" = "Date")) %>%
    group_by(row.x) %>%
    summarise(CumSumB = sum(Qty[row.y <= row.x]))

非常好,可能也添加了一些解释+1干得好!我喜欢你按
row.x
分组的想法,因为这比我按
x,Y
Date
分组要短且容易。
library(dplyr)

dat = dat %>% mutate(row = row_number())
dat %>% 
    left_join(select(dat, X, Date, Y, row), ., by  = c("X" = "Y", "Date" = "Date"))
dat %>% 
    left_join(select(dat, X, Date, Y, row), ., by  = c("X" = "Y", "Date" = "Date")) %>%
    group_by(row.x) %>%
    summarise(CumSumB = sum(Qty[row.y <= row.x]))
dat %>% 
    left_join(select(dat, X, Date, Y, row), ., by  = c("X" = "Y", "Date" = "Date")) %>%
    group_by(row.x) %>%
    summarise(CumSumB = sum(Qty[row.y <= row.x])) %>%
    left_join(dat, ., by = c("row" = "row.x"))

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