Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing a certain range of matrix elements in R

I have a matrix in which I want to zero certain specific elements.

For instance, imagine that my matrix is:

m <- matrix(1:100, ncol=10)

I then have two vectors indicating which elements to keep

m.from <- c(2, 5, 4, 4, 6, 3, 1, 4, 2, 5)
m.to   <- c(7, 9, 6, 8, 9, 5, 6, 8, 4, 8)

So, for instance I will keep elements 3:6 in row 1, and set element 1:2 and 7:10 to 0. For line 2 I will keep 6:8 and zero the rest, and so on.

Now, I could easily do:

for (line in 1:nrow(m))
    {
    m[line, 1:m.from[line]] <- 0
    m[line, m.to[line]:ncol(m)] <- 0
    }

which gives the correct result.

In my specific case, however, I am operating on a ~15000 x 3000 matrix which makes using this kind of loop excruciatingly long.

How can I speed up this code? I though of using apply, but how do I access the correct index of m.from and m.to?

like image 700
nico Avatar asked Dec 07 '22 12:12

nico


1 Answers

Here's a simple matrix oriented solution:

m[col(m) <= m.from] <- 0
m[col(m) >= m.to] <- 0
m
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    0    0   21   31   41   51    0    0    0     0
 [2,]    0    0    0    0    0   52   62   72    0     0
 [3,]    0    0    0    0   43    0    0    0    0     0
 [4,]    0    0    0    0   44   54   64    0    0     0
 [5,]    0    0    0    0    0    0   65   75    0     0
 [6,]    0    0    0   36    0    0    0    0    0     0
 [7,]    0   17   27   37   47    0    0    0    0     0
 [8,]    0    0    0    0   48   58   68    0    0     0
 [9,]    0    0   29    0    0    0    0    0    0     0
[10,]    0    0    0    0    0   60   70    0    0     0

(I think I might win the R Golf prize on this one , too.) For which my entry would be:

m[col(m)<=m.from|col(m)>= m.to]<-0 
like image 142
IRTFM Avatar answered Dec 23 '22 17:12

IRTFM