查找运行/连续值的开始和结束位置/索引

Cla*_*ara 8 r vector run-length-encoding

问题:给定原子矢量,找到矢量中运行的起始和结束索引.

运行示例向量:

x = rev(rep(6:10, 1:5))
# [1] 10 10 10 10 10  9  9  9  9  8  8  8  7  7  6
Run Code Online (Sandbox Code Playgroud)

输出来自rle():

rle(x)
# Run Length Encoding
#  lengths: int [1:5] 5 4 3 2 1
#  values : int [1:5] 10 9 8 7 6
Run Code Online (Sandbox Code Playgroud)

期望的输出:

#   start end
# 1     1   5
# 2     6   9
# 3    10  12
# 4    13  14
# 5    15  15
Run Code Online (Sandbox Code Playgroud)

rle类似乎不提供此功能,但类Rle和函数rle2可以.但是,考虑到功能有多么微小,坚持使用基础R似乎比安装和加载其他软件包更合理.

有一些代码片段的例子(这里,这里SO)解决了为满足某些条件的运行找到开始和结束索引的略有不同的问题.我想要一些更通用的东西,可以在一行中执行,并且不涉及临时变量或值的分配.

回答我自己的问题,因为我对搜索结果缺乏感到沮丧.我希望这有助于某人!

Cla*_*ara 12

核心逻辑:

# Example vector and rle object
x = rev(rep(6:10, 1:5))
rle_x = rle(x)

# Compute endpoints of run
end = cumsum(rle_x$lengths)
start = c(1, lag(end)[-1] + 1)

# Display results
data.frame(start, end)
#   start end
# 1     1   5
# 2     6   9
# 3    10  12
# 4    13  14
# 5    15  15
Run Code Online (Sandbox Code Playgroud)

Tidyverse/dplyrway(以数据框为中心):

library(dplyr)

rle(x) %>%
  unclass() %>%
  as.data.frame() %>%
  mutate(end = cumsum(lengths),
         start = c(1, dplyr::lag(end)[-1] + 1)) %>%
  magrittr::extract(c(1,2,4,3)) # To re-order start before end for display
Run Code Online (Sandbox Code Playgroud)

因为startend向量的长度valuesrle对象的组件长度相同,所以解决为满足某些条件的运行识别端点的相关问题很简单:filter或者使用运行值上的条件对startend向量进行子集化.

  • 同样没有“lag”:“start <- end - rle_x$lengths + 1” (2认同)

Hen*_*rik 5

由运行定义的每个组的data.table可能性,其中.I.N用于选择相关索引rleid

library(data.table)
data.table(x)[ , .(start = .I[1], end = .I[.N]), by = rleid(x)][, rleid := NULL][]
#    start end
# 1:     1   5
# 2:     6   9
# 3:    10  12
# 4:    13  14
# 5:    15  15
Run Code Online (Sandbox Code Playgroud)