R中数据框累积运行长度编码

3
我有一个包含观测值(1或0)的数据框,我想计算连续出现的1的次数,并在0处重新开始计数。运行长度编码函数(rle)似乎可以完成这项工作,但我无法将数据格式化为所需的格式。我想尝试不编写自定义函数来完成此操作。在下面的数据中,我有一个数据框中的观测值,然后我想推导出“continual”列并写回到数据框中。这个链接是一个好的起点
observation continual 
          0         0
          0         0
          0         0
          1         1
          1         2
          1         3
          1         4
          1         5
          1         6
          1         7
          1         8
          1         9
          1        10
          1        11
          1        12
          0         0
          0         0
5个回答

10

你可以通过以下几个简单步骤轻松完成此操作:

x <- rle(mydf$observation)       ## run rle on the relevant column
new <- sequence(x$lengths)       ## create a sequence of the lengths values
new[mydf$observation == 0] <- 0  ## replace relevant values with zero
new
#  [1]  0  0  0  1  2  3  4  5  6  7  8  9 10 11 12  0  0

7
使用最新版本,你可以尝试以下操作:
library(data.table) ## v >= 1.9.5
setDT(df)[, continual := seq_len(.N) * observation, by = rleid(observation)]

当它达到0时,这不会重置。 - Steven Beaupré
4
@Frank,Steve是对的,你的编辑是无效的。这是关于 .I 如何实际工作的最大谜团之一。 - David Arenburg

5

可能有更好的方法,但是:

g <- c(0,cumsum(abs(diff(df$obs))))
df$continual <- ave(g,g,FUN=seq_along)
df$continual[df$obs==0] <- 0

3

只需简单地调整您链接的问题中所接受的答案:

unlist(mapply(function(x, y) seq(x)*y, rle(df$obs)$lengths, rle(df$obs)$values))
# [1]  0  0  0  1  2  3  4  5  6  7  8  9 10 11 12 0  0

2
您可以使用一个简单的基本R一行代码,利用观察结果仅包含01,再加上向量化操作:
transform(df, continual=ifelse(observation, cumsum(observation), observation))

#   observation continual
#1            0         0
#2            0         0
#3            0         0
#4            1         1
#5            1         2
#6            1         3
#7            1         4
#8            1         5
#9            1         6
#10           1         7
#11           1         8
#12           1         9
#13           1        10
#14           1        11
#15           1        12
#16           0         0
#17           0         0

1
如果有额外的1运行,这是否有效?有点模糊,但我想“我想计算连续出现的1,重置为0”。 - Frank
2
当然!我会执行sequence(rle(df1$observation)$lengths),但这与@Aranda的方法完全相同,只是我将代码写得更加紧凑。 - Colonel Beauvel
你可以使用 sequence(rle(df1$observation)$lengths) * df1$observation 来保持零值不变。 - JohannesNE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接