查找 runs/consecutive 个值的开始和结束 positions/indices
Find start and end positions/indices of runs/consecutive values
问题:给定一个原子向量,找到向量中运行的开始和结束索引。
带有游程的示例向量:
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
class 似乎不提供此功能,但 class Rle
and function rle2
提供此功能。然而,考虑到功能是多么的次要,坚持使用基础 R 似乎比安装和加载额外的包更明智。
有一些代码片段示例 (here, here and ) 解决了为满足某些条件的运行查找开始和结束索引的稍微不同的问题。我想要一些更通用的东西,可以在一行中执行,并且不涉及临时变量或值的分配。
回答我自己的问题,因为我对缺少搜索结果感到沮丧。我希望这对某人有所帮助!
核心逻辑:
# 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
因为start
和end
向量与rle
对象的values
分量长度相同,解决了[=识别端点的相关问题26=]s 满足某些条件很简单:filter
或使用 运行 值上的条件对 start
和 end
向量进行子集。
一种 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
问题:给定一个原子向量,找到向量中运行的开始和结束索引。
带有游程的示例向量:
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
class 似乎不提供此功能,但 class Rle
and function rle2
提供此功能。然而,考虑到功能是多么的次要,坚持使用基础 R 似乎比安装和加载额外的包更明智。
有一些代码片段示例 (here, here and
回答我自己的问题,因为我对缺少搜索结果感到沮丧。我希望这对某人有所帮助!
核心逻辑:
# 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
因为start
和end
向量与rle
对象的values
分量长度相同,解决了[=识别端点的相关问题26=]s 满足某些条件很简单:filter
或使用 运行 值上的条件对 start
和 end
向量进行子集。
一种 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