1

我有一个矩阵

      [,1] [,2]
 [1,]    1    3
 [2,]    4    6
 [3,]   11   12
 [4,]   13   14

我想将此矩阵转换为这样的向量:

# indices 1-6, 11-14 = 1, gap indices 7-10 = 0
xx <- c(1,1,1,1,1,1,0,0,0,0,1,1,1,1)

想法:矩阵的值从 1 到 14。向量的长度也是 14。如果假设第一列是start,第二列是end,那么对于矩阵中存在的那些范围,即,1-3、4-6、11-12、13-4(或等效为 1-6、11-14),我希望这些索引处的值在我的输出向量中为 1。和差距应该在我的输出向量中的索引 7-10 处具有 0 值。(感谢编辑)

但是,有时矩阵不会给出矩阵中的最后一个值。但是,我总是知道转换后的大小,比如说,在这种情况下,是 20。那么,结果向量应该是这样的:

# indices 1-6, 11-14 = 1, gap indices 7-10 = 0, indices 15-20 = 0
xx <- c(1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0)

我怎么能在没有循环的情况下做到这一点?我的矩阵很长,我尝试使用循环很慢。

4

3 回答 3

2

这是使用IRanges包的答案:

require(IRanges)
xx.ir <- IRanges(start = xx[,1], end = xx[,2])
as.vector(coverage(xx.ir))
# [1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1

如果您指定整个向量长度的 aminmax值,则:

max.val <- 20
min.val <- 1
c(rep(0, min.val-1), as.vector(coverage(xx.ir)), rep(0, max.val-max(xx)))
于 2013-06-15T07:47:43.670 回答
1

在这里抛出这个,它使用基数 R 并且应该有点快,因为不可避免的循环由以下方式处理rep

zero.lengths <- m[,1] - c(0, head(m[,2], -1)) - 1
one.lengths  <- m[,2] - m[,1] + 1

rep(rep(c(0, 1), nrow(m)),
    as.vector(rbind(zero.lengths, one.lengths)))

或使用其他解决方案sequence

out <- integer(m[length(m)])    # or `integer(20)` following OP's edit.
one.starts  <- m[,1]
one.lengths <- m[,2] - m[,1] + 1
one.idx <- sequence(one.lengths) + rep(one.starts, one.lengths) - 1L
out[one.idx] <- 1L
于 2013-06-15T11:49:59.803 回答
1

@Arun 的回答似乎更好。

现在我明白了这个问题(或者我明白了吗?)。这是基于 R 的一个解决方案,它利用了只需要保留连续的零序列的想法。

find.ones <- function (mat) {
  ones <- rep(0, max(mat))
  ones[c(mat)] <- 1
  ones <- paste0(ones, collapse="")
  ones <- gsub("101", "111", ones)
  ones <- as.numeric(strsplit(ones, "")[[1]])
  ones
}

在 OP 的原始示例中:

m <- matrix(c(1, 3, 4, 6, 11, 12, 13, 14), ncol=2, byrow=TRUE)
find.ones(m)
[1] 1 1 1 1 1 1 0 0 0 0 1 1 1 1

为了对解决方案进行基准测试,让我们制作一个足够大的矩阵:

set.seed(10)
m <- sample.int(n=1e6, size=5e5)                                              
m <- matrix(sort(m), ncol=2, byrow=TRUE)                                           

head(m)                                                           
     [,1] [,2]
[1,]    1    3
[2,]    4    5
[3,]    9   10
[4,]   11   13
[5,]   14   18
[6,]   22   23

system.time(ones <- find.ones(m))

 user  system elapsed 
1.167   0.000   1.167 
于 2013-06-15T07:24:37.737 回答