以mtcars 为例(不理想,因为它不是时间序列,但假设它是并且按时间排序;也让您的数据如此):
df <- mtcars # get sample data
r <- rle(mtcars$mpg < 20) # save run-length encoding
所以r 看起来像
> r
Run Length Encoding
lengths: int [1:9] 4 3 2 8 4 4 3 3 1
values : logi [1:9] FALSE TRUE FALSE TRUE FALSE TRUE ...
现在将其重新排列为data.frame,为行号添加index 列:
r <- with(r, data.frame(lengths, values, index = seq_along(r$lengths)))
所以
> head(r)
lengths values index
1 4 FALSE 1
2 3 TRUE 2
3 2 FALSE 3
4 8 TRUE 4
5 4 FALSE 5
6 4 TRUE 6
将run 索引和value 添加到df,使用rep 重复每个正确的次数:
df$run <- rep(1:nrow(r), times = r$lengths)
df$values <- rep(r$values, times = r$lengths)
将r 切到values 是TRUE 的行,即mpg < 20 所在的行:
r2 <- r[r$values == TRUE,]
现在找到r2 的lengths 最大的index,即最长运行的索引。使用该值将 df 砍到仅那些行,即运行的行。
df2 <- df[df$run == r2[r2$lengths == max(r2$lengths),'index'],]
如果您只想要这些行的第一行和最后一行,
> rbind(df2[1,], df2[nrow(df2),])
mpg cyl disp hp drat wt qsec vs am gear carb run values
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 4 TRUE
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4 4 TRUE
注意:dplyr 可以使这里的语法更直接一点,但步骤几乎相同。