Search code examples
rbioinformaticsbiometricsbioconductor

R: indexes to matrix


I have a matrix call res initially like the following:

      [,1] [,2]
[1,]     0    0
[2,]     0    0
[3,]     0    0
[4,]     0    0
[5,]     0    0
[6,]     0    0
[7,]     0    0
[8,]     0    0
[9,]     0    0
[10,]    0    0 

I have a matrix of indexes (indexes) like the following:

     [,1] [,2]
 [1,]   2    3
 [2,]   7    9

I want the resulting res matrix to be like the following:

      [,1] [,2]
[1,]     0    0
[2,]     1    1
[3,]     1    1
[4,]     0    0
[5,]     0    0
[6,]     0    0
[7,]     1    1
[8,]     1    1
[9,]     1    1
[10,]    0    0 

I have a big matrix, it takes a long time to loop through the indexes matrix. Please let me know if there is a better approach to do this. I am hoping to do something like mat[indexes,] <- 1. However, this does not work I wanted.


Solution

  • If res if your main matrix and indexes is the matrix of indices:

    This could help:

    idx  <- do.call("c",apply(indexes,1,function(x){seq(x[1],x[2])}))
    
    res[idx,] <- 1
    

    As to timing, first create a large indices matrix:

    > set.seed(42)
    > indexes <- t(matrix(sort(sample(1:10000,1000)),2,500))
    > head(indexes)
         [,1] [,2]
    [1,]    3    4
    [2,]   14   16
    [3,]   23   33
    [4,]   40   63
    [5,]   67   74
    [6,]   79   83
    

    and time them:

    > system.time(idx  <- do.call("c",apply(indexes,1,function(x){seq(x[1],x[2])})))   user  system elapsed 
      0.008   0.000   0.007 
    
    > system.time( idx2 <- unlist( apply( indexes , 1 , FUN = function(x){ seq.int(x[1],x[2])}) ))
       user  system elapsed 
      0.004   0.000   0.002
    

    It would appear that the second method is slightly faster.