查找连续值的起始和结束位置/索引

11
问题:给定一个原子向量,找到向量中连续元素的起始索引和结束索引。
具有连续元素的示例向量:
x = rev(rep(6:10, 1:5))
# [1] 10 10 10 10 10  9  9  9  9  8  8  8  7  7  6

rle() 的输出:

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

期望的输出:

#   start end
# 1     1   5
# 2     6   9
# 3    10  12
# 4    13  14
# 5    15  15

基础的rle类似乎没有提供此功能,但是Rle类和rle2函数提供了这个功能。然而,考虑到这个功能并不重要,坚持使用基础R似乎比安装和加载其他软件包更明智。

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

回答自己的问题,因为我对搜索结果的缺乏感到沮丧。希望这可以帮助别人!

2个回答

13

核心逻辑:

# 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

Tidyverse/dplyr方式(以数据框为中心):

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

由于startend向量与rle对象的values组件长度相同,因此解决与满足某些条件的运行的端点识别相关的问题很简单:使用对运行值的条件过滤或子集化startend向量。


嗨@Clara!我在运行你的代码时遇到了一些问题。在你的第一个解决方案中,你是不是指的是dplyr::lag?在你的第二个解决方案中,你是不是想用select代替extract(来自tidyr)?干杯 - Henrik
1
如果您想将第一个解决方案保留在base中,可以使用head(end,-1)代替lag - Henrik
@Henrik 很好的问题!我指的是 stats::lag(我最近也遇到了 dplyrstatslag 上的命名空间冲突问题,所以我理解你为什么会问!)。对于 extract,我指的是 magrittr::extract,它是一个支持前向管道操作符 [ 的函数。感谢您指出这些不明确之处,当时我没有意识到我在做什么! - Clara
感谢您的回复,@Clara!使用stats::lag函数得到的结果与您展示的不同。(start <- c(1, stats::lag(end)[-1] + 1)); [1] 1 10 13 15 16。但是,使用dplyr::lag函数可以得到您展示的结果:(start <- c(1, dplyr::lag(end)[-1] + 1)); [1] 1 6 10 13 15。祝好! - Henrik
2
同时避免“滞后”:start <- end - rle_x$lengths + 1 - qwr

10

使用 rleid 运行定义的分组,.I.N 用于选择相关索引,这是 data.table 的一个可能性。

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

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