我有一个像下面这样的向量:

xx <- c(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1)

我想找到具有索引的索引并将它们组合在一起。在这种情况下,我希望输出在 2x2 矩阵中看起来像 1 6 和 11 14。我的向量实际上很长,所以我无法手动完成。谁能帮我这个?谢谢。

最佳答案

由于问题最初有一个标签“生物信息学”,我将提到 BioconductorIRanges (它是基因组范围的伴侣 GenomicRanges )

> library(IRanges)
> xx <- c(1,1,1,1,1,1,0,0,0,0,1,1,1,1)
> sl = slice(Rle(xx), 1)
> sl
Views on a 14-length Rle subject

views:
    start end width
[1]     1   6     6 [1 1 1 1 1 1]
[2]    11  14     4 [1 1 1 1]

可以强制转换为矩阵,但这对于下一步的任何操作通常都不方便
> matrix(c(start(sl), end(sl)), ncol=2)
     [,1] [,2]
[1,]    1    6
[2,]   11   14

其他操作可能从 Rle 开始,例如,
> xx = c(2,2,2,3,3,3,0,0,0,0,4,4,1,1)
> r = Rle(xx)
> m = cbind(start(r), end(r))[runValue(r) != 0,,drop=FALSE]
> m
     [,1] [,2]
[1,]    1    3
[2,]    4    6
[3,]   11   12
[4,]   13   14

有关 ?Rle 类的全部灵活性,请参阅帮助页面 Rle ;要从上面这样的矩阵转到下面评论中要求的新 Rle,可以创建一个适当长度的新 Rle,然后使用 IRanges 作为索引进行子集分配
> r = Rle(0L, max(m))
> r[IRanges(m[,1], m[,2])] = 1L
> r
integer-Rle of length 14 with 3 runs
  Lengths: 6 4 4
  Values : 1 0 1

人们可以将其扩展为一个完整的向量
> as(r, "integer")
 [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1

但通常最好继续对 Rle 进行分析。该类非常灵活,因此从 xx 到 1 和 0 的整数向量的一种方法是
> as(Rle(xx) > 0, "integer")
 [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1

尽管如此,留在 Rle 空间通常是有意义的。 Arun 对您单独问题的回答可能是最好的。

性能 (速度)很重要,尽管在这种情况下,我认为 Rle 类提供了很大的灵活性,可以抵消较差的性能,并且以矩阵结尾是典型分析不太可能的终点。尽管如此,IRanges 基础设施还是高性能的
eddi <- function(xx)
    matrix(which(diff(c(0,xx,0)) != 0) - c(0,1),
           ncol = 2, byrow = TRUE)

iranges = function(xx) {
    sl = slice(Rle(xx), 1)
    matrix(c(start(sl), end(sl)), ncol=2)
}

iranges.1 = function(xx) {
    r = Rle(xx)
    cbind(start(r), end(r))[runValue(r) != 0, , drop=FALSE]
}


> xx = sample(c(0, 1), 1e5, TRUE)
> microbenchmark(eddi(xx), iranges(xx), iranges.1(xx), times=10)
Unit: milliseconds
          expr       min        lq    median        uq      max neval
      eddi(xx)  45.88009  46.69360  47.67374 226.15084 234.8138    10
   iranges(xx) 112.09530 114.36889 229.90911 292.84153 294.7348    10
 iranges.1(xx)  31.64954  31.72658  33.26242  35.52092 226.7817    10

关于R:压缩索引,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17118286/

10-12 23:21