从非连续向量中查找连续数字的索引号

时间:2017-02-10 19:22:58

标签: r

两部分问题:

Q1

说我有这样的矢量:

y1 <- c(1:4,3,4:7,5,8:15)
y1
 [1]  1  2  3  4  3  4  5  6  7  5  8  9 10 11 12 13 14 15

我想从这个向量中提取,从最小的数字开始,一个连续数字的向量。对于y1,我在此期待:

y_result=1:15
y_result
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

我正在尝试使用is.unsorted(),但到目前为止,我的技能让我失望了。这是我到目前为止的尝试。子集一个向量:

while (is.unsorted(y1) == TRUE) {
  y1 <- y1[which(diff(y1) > 0)]
}
y1
 [1]  1  2  3  4  5  5  8  9 10 11 12 13

这确实产生了未分类的向量。然而,那令人讨厌的五人造成了各种各样的破坏。我看到我的diff()方法是怎么回事,但我不确定如何纠正它。为了清楚起见,我想提取连续数字,删除任何不符合规定的数字。

Q2

对于上述提取,如何提取原始数据的索引值而不是原始值。所以对于这个例子,我一直在寻找回归:

>extract_function()
1,2,3,4,7,8,9,11,12,13,14,15,16,17,18

这里的想法是我能够使用这些索引号从原始数据帧或向量中提取数据。我无法使用match%in%,因为它会返回条件匹配的多个案例。在下面的示例中,由于y2df1$y1中的5&#5匹配5,因此会再次出现讨厌的五种情况:

  df1=data.frame(y1=c(1:4,3,4:7,5,8:15), res=rnorm(y1))
  y2=df1$y1


  while (is.unsorted(y2, strictly=TRUE) == TRUE) {
    y2 <- y2[which(diff(y2) > 0)]
  }

  df1[df1$y1 %in% y2,]

   y1         res
1   1 -0.24592395
2   2 -1.23183844
3   3  0.39394734
4   4  0.53695526
5   3 -1.76993425
6   4  0.14429303
7   5 -0.01816061
10  5 -0.83691178
11  8  0.27537953
12  9 -0.61817703
13 10 -2.17678870
14 11 -0.74117904
15 12 -0.70320352

1 个答案:

答案 0 :(得分:2)

这是一个解决方案,它使用累积的reduce来首先找到索引,然后是值。

consec <- function(x) {
  idx <- unique(Reduce(function(p,i) if(x[i] == x[p]+1) i else p, seq_along(x), acc=TRUE))
  list(idx=idx, val=x[idx])
}

这通过跟踪最后一个连续条目的索引值来工作,仅在新的连续数字到来时才更新它。因此,我们必须过滤到最终答案的唯一指数。

举例,

consec(c(1:4,3,4:7,5,8:15))

$idx
 [1]  1  2  3  4  7  8  9 11 12 13 14 15 16 17 18

$val
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

如果你不是指连续(如差异为1的整数),而是严格增加,那么

ord <- function(x) {
  idx <- unique(Reduce(function(p,i) if(x[i] > x[p]) i else p, seq_along(x), acc=TRUE))
  list(idx=idx, val=x[idx])
}


ord(y1)

$idx
 [1]  1  2  3  4  7  8  9 11 12 13 14 15 16 17 18

$val
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15


y2 <- c(1.097, 1.101, 1.12, 1.12, 1.12, 1.151, 1.201, 1.245, 1.293, 1.379,
        1.482, 1.555, 1.616, 1.669, 1.719, 1.78, 1.842, 1.91, 1.949, 1.959,      
        1.955, 1.939, 1.911, 1.899, 1.903, 1.908, 1.922, 1.918, 1.907, 1.893,
        1.88, 1.877, 1.884, 1.895, 1.903, 1.914, 1.917, 1.913, 1.905, 1.9)

ord(y2)

$idx
 [1]  1  2  3  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

$val
 [1] 1.097 1.101 1.120 1.151 1.201 1.245 1.293 1.379 1.482 1.555 1.616 1.669
[13] 1.719 1.780 1.842 1.910 1.949 1.959