累计计算连续出现病症的次数

时间:2017-03-30 10:37:36

标签: r dataframe data.table cumsum

data.table(或data.frame)中,如何“累计”计算连续发生此类情况的次数?

为了说明,

DT <- data.table(A=c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
                 B=c(1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1))

如果我想添加表示

的列C
  • if(A == B),将1加到当前行的上方。

  • if(A!= B),再次以0

  • 开始

所以答案是

DT <- data.table(A=c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
                 B=c(1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1),
                 C=c(1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1)]

看起来很简单,但我似乎无法做到。我猜它可以建立在这样的东西上吗?

DT[,C:=ifelse(A==B, ??, 0)]

另外,我担心这可能是一个重复的问题,但无法找到它。

2 个答案:

答案 0 :(得分:1)

我们可以使用rleid在'B'上创建分组变量,然后将行序列与'B'相乘以创建'C'

DT[, C := seq_len(.N)*B, .(A, rleid(B))]
DT
#    A B C
# 1: 1 1 1
# 2: 1 0 0
# 3: 1 1 1
# 4: 1 1 2
# 5: 1 0 0
# 6: 1 1 1
# 7: 1 1 2
# 8: 1 1 3
# 9: 1 0 0
#10: 1 1 1
#11: 1 1 2
#12: 1 1 3
#13: 1 1 4
#14: 1 0 0
#15: 1 1 1

答案 1 :(得分:1)

ave R中使用base

x <- with(dt, A==B)
cbind(dt, C = ave(x, cumsum(x == 0), FUN = cumsum))

   # A B C
 # 1: 1 1 1
 # 2: 1 0 0
 # 3: 1 1 1
 # 4: 1 1 2
 # 5: 1 0 0
 # 6: 1 1 1
 # 7: 1 1 2
 # 8: 1 1 3
 # 9: 1 0 0
# 10: 1 1 1
# 11: 1 1 2
# 12: 1 1 3
# 13: 1 1 4
# 14: 1 0 0
# 15: 1 1 1