整数向量的区间长度之和
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
得到length
和 sum
输出。
sum(tapply(int.vec,cumsum(c(TRUE,diff(int.vec) !=1)), FUN=length))
#[1] 10
或使用table
和sum
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 的预期输出只是 vector
的 length
。
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:xn
、x1:xm
、x1:xp
,其中每个向量(或本例中的间隔)的长度为 n
,分别为 m
和 p
。
整个向量的长度为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
假设我有这个整数 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
得到length
和 sum
输出。
sum(tapply(int.vec,cumsum(c(TRUE,diff(int.vec) !=1)), FUN=length))
#[1] 10
或使用table
和sum
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 的预期输出只是 vector
的 length
。
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:xn
、x1:xm
、x1:xp
,其中每个向量(或本例中的间隔)的长度为 n
,分别为 m
和 p
。
整个向量的长度为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