# [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
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

```