根据列创建data.table中的序列

wiz*_*ziw 6 r data.table

说我有以下data.table:

library(data.table)

DT <- data.table(R=sample(0:1, 10000, rep=TRUE), Seq=0)
Run Code Online (Sandbox Code Playgroud)

返回的内容如下:

       R Seq
    1: 1   0
    2: 1   0
    3: 0   0
    4: 0   0
    5: 1   0
   ---      
 9996: 1   0
 9997: 0   0
 9998: 0   0
 9999: 0   0
10000: 1   0
Run Code Online (Sandbox Code Playgroud)

我想生成一个序列(1,2,3,...,n),只要R从前一行改变,它就会重置.想想它就像我在计算一连串随机数.

那么上面会是这样的:

       R Seq
    1: 1   1
    2: 1   2
    3: 0   1
    4: 0   2
    5: 1   1
   ---      
 9996: 1   5
 9997: 0   1
 9998: 0   2
 9999: 0   3
10000: 1   2
Run Code Online (Sandbox Code Playgroud)

思考?

Bro*_*ieG 6

这是一个选项:

set.seed(1)
DT <- data.table(R=sample(0:1, 10000, rep=TRUE), Seq=0L)
DT[, Seq:=seq(.N), by=list(cumsum(c(0, abs(diff(R)))))]
DT
Run Code Online (Sandbox Code Playgroud)

我们创建一个计数器,每当你的0-1变量使用时,它就会递增cumsum(abs(diff(R))).这c(0,部分是为了确保我们得到正确的长度向量.然后我们用它分开by.这会产生:

       R Seq
    1: 0   1
    2: 0   2
    3: 1   1
    4: 1   2
    5: 0   1
   ---      
 9996: 1   1
 9997: 0   1
 9998: 1   1
 9999: 1   2
10000: 1   3
Run Code Online (Sandbox Code Playgroud)

编辑:解决澄清请求:

让我们看看我正在使用的计算by,分解为两个新列:

DT[, diff:=c(0, diff(R))]
DT[, cumsum:=cumsum(abs(diff))]
print(DT, topn=10)
Run Code Online (Sandbox Code Playgroud)

生产:

       R Seq diff cumsum
    1: 0   1    0      0
    2: 0   2    0      0
    3: 1   1    1      1
    4: 1   2    0      1
    5: 0   1   -1      2
    6: 1   1    1      3
    7: 1   2    0      3
    8: 1   3    0      3
    9: 1   4    0      3
   10: 0   1   -1      4
   ---                  
 9991: 1   2    0   5021
 9992: 1   3    0   5021
 9993: 1   4    0   5021
 9994: 1   5    0   5021
 9995: 0   1   -1   5022
 9996: 1   1    1   5023
 9997: 0   1   -1   5024
 9998: 1   1    1   5025
 9999: 1   2    0   5025
10000: 1   3    0   5025
Run Code Online (Sandbox Code Playgroud)

您可以看到每次R改变时,diff的绝对值的累积和如何递增1.然后我们可以使用该cumsum列分解data.table成块,并为每个块生成一个序列,使用seq(.N)该序列计算块中的项目数(.N正好表示每个by组中的项目数).