如何计算元素在data.table中连续出现的次数?

xia*_*dai 5 r data.table

我有一个看起来像这样的data.table

ID, Order, Segment
1, 1, A
1, 2, B
1, 3, B
1, 4, C
1, 5, B
1, 6, B
1, 7, B
1, 8, B
Run Code Online (Sandbox Code Playgroud)

基本上通过使用Order列排序数据.我想了解每个ID的连续B的数量.理想情况下,我想要的输出是

ID, Consec
1, 2
1, 4
Run Code Online (Sandbox Code Playgroud)

因为段B在第2行和第3行连续出现(2次),然后在第5,6,7,8行(4次)连续出现.

循环解决方案非常明显,但也很慢.

data.table中有优雅的解决方案吗?

PS我正在处理的数据有大约2000万行.

akr*_*run 10

尝试

 library(data.table)#v1.9.5+
  DT[order(ID, Order)][, indx:=rleid(Segment)][Segment=='B',
    list(Consec=.N), by = list(indx, ID)][,indx:=NULL][]

 #    ID Consec
 #1:  1      2
 #2:  1      4
Run Code Online (Sandbox Code Playgroud)

或者像@eddi建议的那样

 DT[order(ID, Order)][, .(Consec = .N), by = .(ID, Segment, 
              rleid(Segment))][Segment == 'B', .(ID, Consec)]
 #    ID Consec
 #1:  1      2
 #2:  1      4
Run Code Online (Sandbox Code Playgroud)

一种更有效的内存方法是使用setorder而不是order(正如@Arun所建议的那样)

  setorder(DT, ID, Order)[, .(Consec = .N), by = .(ID, Segment, 
                rleid(Segment))][Segment == 'B', .(ID, Consec)]
  #   ID Consec
  #1:  1      2
  #2:  1      4
Run Code Online (Sandbox Code Playgroud)

  • 你真的不需要显式创建一个新列,并且可以动态执行:`DT [order(ID,Order)] [,.(Consec = .N),by =.(ID,Segment,rleid (Segment))] [Segment =='B',.(ID,Consec)]` (6认同)