【问题标题】:Extract first continuous sequence in vector提取向量中的第一个连续序列
【发布时间】:2017-07-13 07:42:14
【问题描述】:

我有一个向量:

as <- c(1,2,3,4,5,9)

我需要提取向量中的第一个连续序列,从索引 1 开始,输出如下:

1 2 3 4 5

是否有这样做的智能功能,或者我必须做一些不那么优雅的事情:

a <- c(1,2,3,4,5,9)
is_continunous <- c()
for (i in 1:length(a)) {
  if(a[i+1] - a[i] == 1) {
    is_continunous <- c(is_continunous, i)
  } else {
    break
  }
}

continunous_numbers <- c()
if(is_continunous[1] == 1) {
  is_continunous <- c(is_continunous, length(is_continunous)+1)
  continunous_numbers <- a[is_continunous]
}

它可以解决问题,但我希望有一个函数可以做到这一点。

【问题讨论】:

  • @Sotos 如果输入是as &lt;- c(4,3,1,2,3,4,5,9) 呢?
  • @zx8754 是的......这似乎太容易了:)
  • 可能类似于d1&lt;- which(diff(as) == 1); as[c(d1, d1[length(d1)]+1)]?
  • @Sotos 可能会作为答案发布,但感觉这是一个骗局。
  • @Cath 这就是我没有发布答案的原因。我想既然OP澄清了,那我应该回答它......?

标签: r indexing continuous


【解决方案1】:

不清楚如果连续序列的索引仅从索引 1 或第一个序列开始,无论起始索引是什么。

在这两种情况下,您都需要从检查相邻元素之间的差异开始:

d_as <- diff(as)

如果您只需要从索引 1 开始的第一个序列:

if(d_as[1]==1) 1:(rle(d_as)$lengths[1]+1) else NULL
# [1] 1 2 3 4 5

rle 允许知道每个具有相同值的连续序列的长度和值。

如果您需要第一个连续序列,无论起始索引是什么:

rle_d_as <- rle(d_as)
which(d_as==1)[1]+(0:(rle_d_as$lengths[rle_d_as$values==1][1]))

示例(第二个选项):

as <- c(1,2,3,4,5,9) 
d_as <- diff(as)
rle_d_as <- rle(d_as)
which(d_as==1)[1]+(0:(rle_d_as$lengths[rle_d_as$values==1][1]))
#[1] 1 2 3 4 5

as <- c(4,3,1,2,3,4,5,9)
d_as <- diff(as)
rle_d_as <- rle(d_as)
which(d_as==1)[1]+(0:(rle_d_as$lengths[rle_d_as$values==1][1]))
# [1] 3 4 5 6 7

as <- c(1, 2, 3, 6, 7, 8)
d_as <- diff(as)
rle_d_as <- rle(d_as)
which(d_as==1)[1]+(0:(rle_d_as$lengths[rle_d_as$values==1][1]))
# [1] 1 2 3

【讨论】:

  • 感谢您的全面回答。
  • @EsbenEickhardt 不客气我很高兴它有帮助:-)
【解决方案2】:

捕获序列的一种简单方法是找到向量的diff,并使用diff == 1 以及下一个元素获取所有元素,即

d1<- which(diff(as) == 1)
as[c(d1, d1[length(d1)]+1)]

注意

这只有在你的向量中只有一个序列时才有效。但是,如果我们想让它更通用,那么我建议这样创建一个函数,

get_seq <- function(vec){
  d1 <-  which(diff(as) == 1)
  if(all(diff(d1) == 1)){
    return(c(d1, d1[length(d1)]+1))
  }else{
    d2 <- split(d1, cumsum(c(1, diff(d1) != 1)))[[1]]
    return(c(d2, d2[length(d2)]+1))
  }
}


#testing it

as <- c(3, 5, 1, 2, 3, 4, 9, 7, 5, 4, 5, 6, 7, 8)
get_seq(as)
#[1] 3 4 5 6

as <- c(8, 9, 10, 11, 1, 2, 3, 4, 7, 8, 9, 10)
get_seq(as)
#[1]  1 2 3 4

as <- c(1, 2, 3, 4, 5, 6, 11)
get_seq(as)
#[1] 1 2 3 4 5 6

【讨论】:

  • 感谢您的回答。我不是想偷你的答案,只是想让人们知道我得到了满意的答案并且我的问题得到了回答。
  • @EsbenEickhardt 不用担心。你做得不错。我知道你的意思很好:)
  • @EsbenEickhardt 制作了一个在任何情况下都可以使用的函数
  • 酷,谢谢!我相信这在其他情况下会派上用场。
  • @EsbenEickhardt 只是为了澄清。您需要返回连续值的索引,而不是值本身对吗? (您的示例不清楚,因为您在索引 1、2、3、4、5 处有值 1、2、3、4、5):)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
相关资源
最近更新 更多