根据不同的列子集并汇总原始data.table

wol*_*oor 4 r data.table

这是非常困难的,但是我正在尝试执行标题中所说的操作,例如,假设我有一个数据表,dat并且我正在尝试计算新列中的累加总和(从第一列和第三列开始,当第二列出现时))出现在第二栏中。

dat = data.table(A=c(1,2,3,1,4,5,1,2,3),B=c(1,1,1,NA,1,NA,2,NA,2),C=c(1,12,24.2,251,2,1,2,3,-1))
dat[,cumsum:=0]
Run Code Online (Sandbox Code Playgroud)

所以数据看起来像

   > dat
   A  B     C
1: 1  1   1.0
2: 2  1  12.0
3: 3  1  24.2
4: 1 NA 251.0
5: 4  1   2.0
6: 5 NA   1.0
7: 1  2   2.0
8: 2 NA   3.0
9: 3  2  -1.0
Run Code Online (Sandbox Code Playgroud)

我希望输出是这样的:

> dat
   A  B     C cumsum
1: 1  1   1.0      1
2: 2  1  12.0      1
3: 3  1  24.2      1
4: 1 NA 251.0      0
5: 4  1   2.0      252
6: 5 NA   1.0      0
7: 1  2   2.0      12
8: 2 NA   3.0      0
9: 3  2  -1.0      15
Run Code Online (Sandbox Code Playgroud)

有一种有效的数据表方法可以做到这一点吗?我可以使用循环来执行此操作,但是这样做会很慢,而且我认为这必须以更可扩展的方式来实现,但我遇到了麻烦。

chi*_*n12 6

一种使用非等价自连接的可能方法:

dat[, rn := .I]
dat[!is.na(B), cumsum := dat[.SD, on=.(A=B, rn<=rn), sum(x.C), by=.EACHI]$V1]
Run Code Online (Sandbox Code Playgroud)

输出:

   A  B     C cumsum rn
1: 1  1   1.0      1  1
2: 2  1  12.0      1  2
3: 3  1  24.2      1  3
4: 1 NA 251.0      0  4
5: 4  1   2.0    252  5
6: 5 NA   1.0      0  6
7: 1  2   2.0     12  7
8: 2 NA   3.0      0  8
9: 3  2  -1.0     15  9
Run Code Online (Sandbox Code Playgroud)

数据:

dat = data.table(A=c(1,2,3,1,4,5,1,2,3),B=c(1,1,1,NA,1,NA,2,NA,2),C=c(1,12,24.2,251,2,1,2,3,-1))
dat[,cumsum:=0]
Run Code Online (Sandbox Code Playgroud)

编辑:添加另一种方法,灵感来自弗兰克的答案

dat = data.table(A=c(1,2,3,1,4,5,1,2,3),B=c(1,1,1,NA,1,NA,2,NA,2),C=c(1,12,24.2,251,2,1,2,3,-1))
dat[, rn := .I][, cs := cumsum(C), A]
dat[, cumsum := 0][
    !is.na(B), cumsum :=  dat[.SD, on=.(A=B, rn), allow.cartesian=TRUE, roll=TRUE, x.cs]]
Run Code Online (Sandbox Code Playgroud)