向包含行的data.table添加倒计时列,直到遇到特殊行

Cor*_*one 6 r data.table

我有一个data.table有序的数据标签,我想添加一个列,告诉我有多少记录,直到我得到一个重置倒计时的"特殊"记录.

例如:

DT = data.table(idx = c(1,3,3,4,6,7,7,8,9), 
                name = c("a", "a", "a", "b", "a", "a", "b", "a", "b"))
setkey(DT, idx)
#manually add the answer
DT[, countdown := c(3,2,1,0,2,1,0,1,0)]
Run Code Online (Sandbox Code Playgroud)

> DT
   idx name countdown
1:   1    a         3
2:   3    a         2
3:   3    a         1
4:   4    b         0
5:   6    a         2
6:   7    a         1
7:   7    b         0
8:   8    a         1
9:   9    b         0
Run Code Online (Sandbox Code Playgroud)

查看倒计时列如何告诉我有多少行,直到一行称为"b".问题是如何在代码中创建该列.

请注意,键的间距不均匀,可能包含重复项(因此在解决问题时不是很有用).一般来说,非b名称可能不同,但如果解决方案需要,我可以添加一个只有True/False的虚拟列.

Jos*_*ien 7

这是另一个想法:

## Create groups that end at each occurrence of "b"
DT[, cd:=0L]
DT[name=="b", cd:=1L]
DT[, cd:=rev(cumsum(rev(cd)))]
## Count down within them
DT[, cd:=max(.I) - .I, by=cd]
#    idx name cd
# 1:   1    a  3
# 2:   3    a  2
# 3:   3    a  1
# 4:   4    b  0
# 5:   6    a  2
# 6:   7    a  1
# 7:   7    b  0
# 8:   8    a  1
# 9:   9    b  0
Run Code Online (Sandbox Code Playgroud)


A5C*_*2T1 6

我确信(或者至少有希望)会产生一个纯粹的"data.table"解决方案,但与此同时,你可以利用它rle.在这种情况下,您有兴趣倒转倒计时,因此我们将rev在继续之前使用反转"名称"值.

output <- sequence(rle(rev(DT$name))$lengths)
makezero <- cumsum(rle(rev(DT$name))$lengths)[c(TRUE, FALSE)]
output[makezero] <- 0

DT[, countdown := rev(output)]
DT
#    idx name countdown
# 1:   1    a         3
# 2:   3    a         2
# 3:   3    a         1
# 4:   4    b         0
# 5:   6    a         2
# 6:   7    a         1
# 7:   7    b         0
# 8:   8    a         1
# 9:   9    b         0
Run Code Online (Sandbox Code Playgroud)

  • @Corone - 你没有说的一件事就是你想要发生的事情(如果有的话)连续两个"b".Ananda和我的答案在这种情况下有所不同:我给两者都指定一个'0',而他在第一个"b"之后开始倒数第二组. (3认同)