R:浓缩指数

use*_*809 4 r

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

xx <- c(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1)
Run Code Online (Sandbox Code Playgroud)

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

Aru*_*run 5

也许是这样的事情?

if (xx[1] == 1) {
    rr <- cumsum(c(0, rle(xx)$lengths))
} else {
    rr <- cumsum(rle(xx)$lengths)
}
if (length(rr) %% 2 == 1) {
    rr <- head(rr, -1)
}
oo <- matrix(rr, ncol=2, byrow=TRUE)
oo[, 1] <- oo[, 1] + 1
     [,1] [,2]
[1,]    1    6
[2,]   11   14
Run Code Online (Sandbox Code Playgroud)

该编辑处理以下情况:1)向量以"0"开始而不是"1"和2),其中1的连续出现次数是奇数/偶数.例如:xx <- c(1,1,1,1,1,1,0,0,0,0).


Mar*_*gan 5

由于这个问题最初有一个标签'生物信息学',我会提到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]
Run Code Online (Sandbox Code Playgroud)

它可以被强制转换为矩阵,但对于下一步而言,这通常是不方便的

> matrix(c(start(sl), end(sl)), ncol=2)
     [,1] [,2]
[1,]    1    6
[2,]   11   14
Run Code Online (Sandbox Code Playgroud)

其他操作可能会开始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
Run Code Online (Sandbox Code Playgroud)

请参阅帮助页面?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
Run Code Online (Sandbox Code Playgroud)

可以将其扩展为完整向量

> as(r, "integer")
 [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)

但通常最好继续对Rle进行分析.该类非常灵活,因此从xx1到0的整数向量的一种方法是

> as(Rle(xx) > 0, "integer")
 [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)

但是,再次,留在Rle空间通常是有意义的.而阿伦对你的单独问题的回答可能是最好的.

性能(速度)很重要,尽管在这种情况下我认为Rle类提供了很大的灵活性,可以衡量性能不佳,而最终的矩阵是典型分析的一个不太可能的终点.Nonangheles 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]
}
Run Code Online (Sandbox Code Playgroud)

> 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
Run Code Online (Sandbox Code Playgroud)