[R] Creating efficiently a subset of a matrix

Prof Brian D Ripley ripley at stats.ox.ac.uk
Fri Feb 11 09:07:10 CET 2000


On Fri, 11 Feb 2000, Peter Holzer wrote:

> I have the following problem: given a  m x n matrix A, I want to have just a
> m x k submatrix B, with B[i,] = A[i, offset[i] + 1:k], e.g. from
> 
> > offset <- c(0, 0, 1)
> > a <- matrix(1:9, 3)
> > a
>      [,1] [,2] [,3]
> [1,]    1    4    7
> [2,]    2    5    8
> [3,]    3    6    9
> 
> the submatrix b
> 
> 1 4
> 2 5
> 6 9
> 
> I can do this with a for loop or with sapply
> 
> > b <- sapply(seq(offset), function(x) a[x,offset[x]+1:2])
> ## result is transposed
> 
> However, comparing the two possibilities on a 10000 x 100 matrix and a
> submatrix of 10000 x 50 it turned out (using system.time) that the for loop
> was faster (about 20%).

Unless you used R-0.99.0, sapply _is_ a for loop.

> Is there a more efficient way to achieve the desired result?

Yes, matrix indexing (at least in theory).  You want the following elements
of `a':

1 1
2 1
3 2
1 2
1 2
2 3

and you can use that matrix as an index. As in

ind <- cbind(seq(nrow(a)), as.vector(outer(offset, seq(k), "+")))
matrix(a[ind],,k)
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    6    9

Now, your matrices are pretty large, and however I was doing it I would
do this in chunks of rows at a time.


-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272860 (secr)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list