[R] Creating a Sparse Matrix from a Sparse Vector
Martin Maechler
maechler at stat.math.ethz.ch
Tue Jan 20 22:21:01 CET 2009
>>>>> "B" == BDGrantham <BDGrantham at Hormel.com>
>>>>> on Tue, 20 Jan 2009 11:53:55 -0600 writes:
B> Hello,
B> I am working with a sparse matrix that is approx. 13,900 by 14,100. My
B> goal is to select a row out of the matrix and create a new matrix with that
B> row repeated 13,900 times without having to do any looping. Example:
B> Starting Matrix:
B> exampleMatrix
B> 3 x 4 sparse Matrix of class "dgCMatrix"
B> [1,] 1 . . .
B> [2,] . 1 . 0.5
B> [3,] . . 1 ..
B> New Matrix:..
B> newExampleMatrix
B> 3 x 4 sparse Matrix of class "dgCMatrix"
B> [1,] . 1 . 0.5
B> [2,] . 1 . 0.5
B> [3,] . 1 . 0.5
B> When I try the following I get a memory allocation error due to the size of
B> the array or vector:
{the following is too ugly for me to deparse ..}
If you used variable names of one or two letters, spaces and
proper indentation, that would have been a different business.
B> newExampleMatrix<-Matrix(rep(exampleMatrix[2,],times=nrow
B> (exampleMatrix)),nrow=nrow(exampleMatrix),ncol=ncol
B> (exampleMatrix),byrow=TRUE,sparse=TRUE)
B> newExampleMatrix<-Matrix(exampleMatrix[2,],nrow=nrow
B> (exampleMatrix),ncol=ncol(exampleMatrix),byrow=TRUE,sparse=TRUE)
Matrix() should not be used for large sparse matrices.
It's input, when not a sparseMatrix must be *dense* in one way
or the other.
The real solution of course is to step back and think a bit:
What will the (i,j,x) [triplet aka "Tsparse"]
or (i,p,x) [column-compressed aka "Csparse"]
structure be.
After a fraction of a second you'll see that the triplet
representation will be trivial .... more on that below.
B> When I tried the next set, I got the error "Error in Matrix(as(rep
B> (exampleMatrix[2, ], times = nrow(exampleMatrix)), : invalid type/length
B> (S4/12) in vector allocation":
B> newExampleMatrix<-Matrix(as(rep(exampleMatrix[2,],times=nrow
B> (exampleMatrix)),"sparseVector"),nrow=nrow(exampleMatrix),ncol=ncol
B> (exampleMatrix),byrow=TRUE,sparse=TRUE)
B> newExampleMatrix<-Matrix(as(exampleMatrix[2,],"sparseVector"),nrow=nrow
B> (exampleMatrix),ncol=ncol(exampleMatrix),byrow=TRUE,sparse=TRUE)
B> And finally, when I tried the next instruction, I got the error "Error in
B> as.vector(x, mode) : cannot coerce type 'S4' to vector of type 'any' Error
Here seem to have loaded "SparseM" additionally to "Matrix",
not something useful at all here ..
B> in as.matrix.csc(as.matrix.csr(x)) : error in evaluating the argument 'x'
B> in selecting a method for function 'as.matrix.csc'" :
B> as.matrix.csc(as(rep(currentMatrix[pivitRow,],times=nrow
B> (currentMatrix)),"sparseVector"),nrow=nrow(currentMatrix),ncol=ncol
B> (currentMatrix))
B> Are there any other ways to accomplish this?],
yes; many, as always with R.
Since I'm sick in bed and cannot really do rocket science (:-)
I've solved this exercise for you:
require("Matrix")
repRow <- function(m, i, times)
{
## Purpose: return a sparse matrix containing row m[i,] 'times' times
## ----------------------------------------------------------------------
## Arguments: m: sparseMatrix; i: row index; times: #{replicates}
## ----------------------------------------------------------------------
## Author: Martin Maechler, Date: 20 Jan 2009, 21:48
stopifnot(is(m, "sparseMatrix"),
length(i) == 1, length(times <- as.integer(times)) == 1,
i >= 1, times >= 0, i == as.integer(i))
cl <- class(m)
m <- as(m, "TsparseMatrix")
mi <- m[i,, drop=FALSE]
## result: replace the parts of 'm':
r <- new(class(mi))
r at Dim <- c(times, m at Dim[2])
r at i <- rep.int(seq_len(times) - 1L, length(mi at j))
r at j <- rep(mi at j, each = times)
r at Dimnames <- list(NULL, mi at Dimnames[[2]])
if(!extends(cl, "nMatrix")) ## have 'x' slot
r at x <- rep(mi at x, each = times)
validObject(r)
if(extends(cl, "CsparseMatrix")) as(r, "CsparseMatrix") else r
}
(m <- Matrix(c(0,0,2:0), 3,5))
repRow(m,3, 7)
repRow(m,2, 11)
repRow(m,1, 1)
repRow(m,1, 0) # even that works
## now with a big (very sparse) one:
M <- kronecker(m, diag(1000))
r <- repRow(M,2, 4) # still quite quick
##-------------
Best regards,
Martin Maechler, ETH Zurich
More information about the R-help
mailing list