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