在R中,找到1个或多个数字增加1的序列的开始和结束索引的有效方法是什么



我有一个数字向量:
SampleVector <- c(2,4,7,8,9,12,14,16,17,19,23,24,25,26,27,29)
我想在增加1的序列的开始和结束处找到元素的索引,但我也想要不属于序列的元素的索引
另一种说法是:我想要不在单步序列中的所有元素的索引
对于SampleVector,我想要的索引是:
DesiredIndices <- c(1,2,3,5,6,7,8,9,10,11,15,16)
也就是说,除了数字8(按7:9顺序(和数字24、25和26(按23:27顺序(之外的所有索引。
到目前为止,我最好的尝试是:

SequenceStartAndEndIndices <- function(vector){
DifferenceVector          <- diff(vector)
DiffRunLength             <- rle(DifferenceVector)
IndicesOfSingleElements   <- which(DifferenceVector > 1) + 1
IndicesOfEndOfSequences   <- cumsum(DiffRunLength$lengths)[which((DiffRunLength$lengths * DiffRunLength$values) == DiffRunLength$lengths)] + 1
IndicesOfStartsOfSequences<- c(1,head(IndicesOfEndOfSequences+1,-1))
UniqueIndices             <- unique(c(IndicesOfStartsOfSequences,IndicesOfEndOfSequences,IndicesOfSingleElements))
SortedIndices             <- UniqueIndices[order(UniqueIndices)]
return(SortedIndices)
}

这个功能给了我正确的答案:

> SequenceStartAndEndIndices(vector = SampleVector)
[1]  1  2  3  5  6  7  8  9 10 11 15 16

但这几乎是不可能遵循的,它的普遍适用性也不明显。是否有更好的方法,或者某个包中的现有函数?

作为背景,这样做的目的是帮助将距离标记的长向量解析为合理的人类可读的东西,例如;公里数:1,8,9,10,11,13";我将能够提供";公里数:1、8至11和13";。

您可以尝试在R基中使用tapply来创建连续数字组。

SampleVector <- c(2,4,7,8,9,12,14,16,17,19,23,24,25,26,27,29)
toString(tapply(SampleVector, 
cumsum(c(TRUE, diff(SampleVector) > 1)), function(x) {
if(length(x) == 1) x else paste(x[1], x[length(x)], sep = ' to ')
}))
#[1] "2, 4, 7 to 9, 12, 14, 16 to 17, 19, 23 to 27, 29"

这应该有效,因为如果:1(值比上一个值大1,则不包括值的索引;2( 比下一个少1。

> x <- diff(SampleVector)
> seq_along(SampleVector)[!(c(0, x) == 1 & c(x, 0) == 1)]
[1]  1  2  3  5  6  7  8  9 10 11 15 16

最新更新