整数向量的区间长度之和

Sum of intervals lengths from an integer vector

假设我有这个整数 vector:

> int.vec
 [1]  1  2  3  5  6  7 10 11 12 13

(创建自 int.vec <- c(1:3,5:7,10:13)

我正在寻找一个函数,它将 return 此向量中所有区间的长度总和。

所以基本上 int.vec 这个函数将 return:

3+3+4 = 10

我们可以通过取相邻元素的差异来创建一个分组变量,检查是否不等于1,得到cumsum,使用tapply得到lengthsum 输出。

sum(tapply(int.vec,cumsum(c(TRUE,diff(int.vec) !=1)), FUN=length))
#[1] 10

或使用tablesum

sum(table(int.vec,cumsum(c(TRUE,diff(int.vec) !=1))))
#[1] 10

或者我们 split "int.vec" 与派生自 cumsum 的分组变量(split 非常快)并得到每个 length =24=] 元素与 lengths (另一个快速选项) - 由@Frank

贡献
sum(lengths(split(int.vec, cumsum(c(0,diff(int.vec)>1)))))

注意:未使用包。这将有助于通过删除 sum 包装器来识别每个组件的个体 length(以防我们需要)。


根据@Symbolix 解决方案的进一步见解,OP 的预期输出只是 vectorlength

NROW(int.vec)
#[1] 10

也可以使用。这也适用于我们使用 data.frame 的情况。但是,正如我上面提到的,OP 似乎需要识别每个间隔的 length 以及 length。此解决方案提供了两者。

"cgwtools" 包中有一个名为 seqle 的函数,在这里可能会有用。

library(cgwtools)
int.vec <- c(1:3,5:7,10:13)
seqle(int.vec)
# Run Length Encoding
#   lengths: int [1:3] 3 3 4
#   values : int [1:3] 1 5 10

结果是 list,因此您只需访问 "lengths" 值并将其求和:

sum(seqle(int.vec)$lengths)
# [1] 10
length(int.vec)
# 10

您的间隔是数字序列,x1:xnx1:xmx1:xp,其中每个向量(或本例中的间隔)的长度为 n,分别为 mp

整个向量的长度为length(x1:xn) + length(x1:xm) + length(x1:xp), 这与 length(n + m + p).

相同

现在,如果我们真的对序列的每个单独向量的长度感兴趣,我们可以这样做

int.vec <- c(1:3,5:7,10:13)

## use run-length-encoding (rle) to find sequences where the difference == 1
v <- rle(diff(int.vec) == 1)[[1]]
v[v!=1] + 1
# [1] 3 3 4

而且,正如@AHandcartAndMohair 所指出的,如果您正在使用列表,您可以使用 lengths

int.list <- list(c(1:3), c(5:7), c(10:13))
lengths(int.list)
# [1] 3 3 4