[R] Matrix: How create a _row-oriented_ sparse Matrix (=dgRMatrix)?
Henrik Bengtsson
henrik.bengtsson at gmail.com
Wed Apr 20 22:00:47 CEST 2016
On Wed, Apr 20, 2016 at 1:25 AM, Martin Maechler
<maechler at stat.math.ethz.ch> wrote:
>>>>>> Henrik Bengtsson <henrik.bengtsson at gmail.com>
>>>>>> on Tue, 19 Apr 2016 14:04:11 -0700 writes:
>
> > Using the Matrix package, how can I create a row-oriented sparse
> > Matrix from scratch populated with some data? By default a
> > column-oriented one is created and I'm aware of the note that the
> > package is optimized for column-oriented ones, but I'm only interested
> > in using it for holding my sparse row-oriented data and doing basic
> > subsetting by rows (even using drop=FALSE).
>
> > Here is what I get when I set up a column-oriented sparse Matrix:
>
> >> Cc <- Matrix(0, nrow=5, ncol=5, sparse=TRUE)
> >> Cc[1:3,1] <- 1
>
> A general ("teaching") remark :
> The above use of Matrix() is seen in many places, and is fine
> for small matrices and the case where you only use the `[<-`
> method very few times (as above).
> Also using Matrix() is nice when being introduced to using the
> Matrix package.
>
> However, for efficience in non-small cases, do use
>
> sparseMatrix()
>
> directly to construct sparse matrices.
>
>
> >> Cc
> > 5 x 5 sparse Matrix of class "dgCMatrix"
>
> > [1,] 1 . . . .
> > [2,] 1 . . . .
> > [3,] 1 . . . .
> > [4,] . . . . .
> > [5,] . . . . .
> >> str(Cc)
> > Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
> > ..@ i : int [1:3] 0 1 2
> > ..@ p : int [1:6] 0 3 3 3 3 3
> > ..@ Dim : int [1:2] 5 5
> > ..@ Dimnames:List of 2
> > .. ..$ : NULL
> > .. ..$ : NULL
> > ..@ x : num [1:3] 1 1 1
> > ..@ factors : list()
>
> > When I try to do the analogue for a row-oriented matrix, I get a
> > "dgTMatrix", whereas I would expect a "dgRMatrix":
>
> >> Cr <- Matrix(0, nrow=5, ncol=5, sparse=TRUE)
> >> Cr <- as(Cr, "dsRMatrix")
> >> Cr[1,1:3] <- 1
> >> Cr
> > 5 x 5 sparse Matrix of class "dgTMatrix"
>
> > [1,] 1 1 1 . .
> > [2,] . . . . .
> > [3,] . . . . .
> > [4,] . . . . .
> > [5,] . . . . .
>
> The reason for the above behavior has been
>
> a) efficiency. All the subassignment ( `[<-` ) methods for
> "RsparseMatrix" objects (of which "dsRMatrix" is a special case)
> are implemented via TsparseMatrix.
> b) because of the general attitude that Csparse (and Tsparse to
> some extent) are well supported in Matrix,
> and e.g. further operations on Rsparse matrices would *again*
> go via T* or C* sparse ones, I had decided to keep things Tsparse.
Thanks, understanding these design decisions is helpful.
Particularly, since I consider myself a rookie when it comes to the
Matrix package.
>
> [...]
>
> > Trying with explicit coercion does not work:
>
> >> as(Cc, "dgRMatrix")
> > Error in as(Cc, "dgRMatrix") :
> > no method or default for coercing "dgCMatrix" to "dgRMatrix"
>
> >> as(Cr, "dgRMatrix")
> > Error in as(Cr, "dgRMatrix") :
> > no method or default for coercing "dgTMatrix" to "dgRMatrix"
>
> The general philosophy in 'Matrix' with all the class
> hierarchies and the many specific classes has been to allow and
> foster coercing to abstract super classes,
> i.e, to "dMatrix" or "generalMatrix", "triangularMatrix", or
> then "denseMatrix", "sparseMatrix", "CsparseMatrix" or
> "RsparseMatrix", etc
>
> So in the above as(*, "RsparseMatrix") should work always.
Thanks for pointing this out (and confirming as I since discovered the
virtual RsparseMatrix class in the help).
>
>
> As a summary, in other words, for what you want,
>
> as(sparseMatrix(.....), "RsparseMatrix")
>
> should give you what you want reliably and efficiently.
Perfect.
>
>
> > Am I doing some wrong here? Or is this what means that the package is
> > optimized for the column-oriented representation and I shouldn't
> > really work with row-oriented ones? I'm really only interested in
> > access to efficient Cr[row,,drop=FALSE] subsetting (and a small memory
> > footprint).
>
> { though you could equivalently use Cc[,row, drop=FALSE]
> with a CsparseMatrix Cc := t(Cr),
> couldn't you ?
> }
Yes, I actually went ahead did that, but since the code I'm writing
supports both plain matrix:es and sparse Matrix:es, and the underlying
model operates row-by-row, I figured the code would be more consistent
if I could use row-orientation everywhere. Not a big deal.
Thanks Martin
Henrik
>
>
> Martin Maechler (maintainer of 'Matrix')
> ETH Zurich
>
More information about the R-help
mailing list