如何找到连续数字的区间起始和结束位置?

3

我有一个向量。

vec <- c(2, 3, 5, 6, 7, 8, 16, 19, 22, 23, 24)

连续数字是:
c(2, 3)
c(5, 6, 7, 8)
c(22, 23, 24)

第一个向量从2开始,到3结束;

第二个向量从5开始,到8结束;

第三个向量从22开始,到24结束;

有一个函数可以识别连续的数字开始和结束的位置吗?


1
你是否更好地说你正在寻找“连续整数”? - Fred Boehm
2个回答

5
通过使用diff检查每个连续值之间的差异,您可以找到差异不是+1的位置。
diff(vec)
## [1] 1 2 1 1 1 8 3 3 1 1
c(1, diff(vec)) != 1
## [1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE

然后使用cumsum生成一个分组标识符:

cumsum(c(1, diff(vec))!=1)
## [1] 0 0 1 1 1 1 2 3 4 4 4

使用这个方法来 分割 你的数据:

split(vec, cumsum(c(1, diff(vec))!=1))
##$`0`
##[1] 2 3
##
##$`1`
##[1] 5 6 7 8
##
##$`2`
##[1] 16
##
##$`3`
##[1] 19
##
##$`4`
##[1] 22 23 24

可以被过滤成连续的值:

Filter(\(x) length(x) > 1, split(vec, cumsum(c(1, diff(vec))!=1)))
##$`0`
##[1] 2 3
##
##$`1`
##[1] 5 6 7 8
##
##$`4`
##[1] 22 23 24

那么现在我需要对列表中的每个元素应用一个函数来找到第一个和最后一个数字,对吗? - RoBrT
@RoBrT - 如果你只需要起点和终点,可以对输出进行循环 - lapply(out, \(x) c(x[1], x[length(x)]) ) - thelatemail

3

另一个

vec=c( 2  ,  3  ,  5  ,  6  ,  7 ,   8   ,  16 , 19 , 22 , 23 , 24 )

x <- replace(NA, vec, vec)
# [1] NA  2  3 NA  5  6  7  8 NA NA NA NA NA NA NA 16 NA NA 19 NA NA 22 23 24

l <- split(x, with(rle(is.na(x)), rep(seq.int(length(lengths)), lengths)))
# l <- split(x, data.table::rleid(is.na(x))) ## same as above
l <- Filter(Negate(anyNA), l)
l
# $`2`
# [1] 2 3
# 
# $`4`
# [1] 5 6 7 8
# 
# $`6`
# [1] 16
# 
# $`8`
# [1] 19
# 
# $`10`
# [1] 22 23 24

如果您有长度要求:

l[lengths(l) > 1]
# $`2`
# [1] 2 3
# 
# $`4`
# [1] 5 6 7 8
# 
# $`10`
# [1] 22 23 24

聪明地使用 replace。不得不查看文档才能理解为什么这样做是有效的..回收利用。 - user20650

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