BDGrantham at Hormel.com
2009-Jan-20 17:53 UTC
[R] Creating a Sparse Matrix from a Sparse Vector
Hello, I am working with a sparse matrix that is approx. 13,900 by 14,100. My goal is to select a row out of the matrix and create a new matrix with that row repeated 13,900 times without having to do any looping. Example: Starting Matrix: exampleMatrix 3 x 4 sparse Matrix of class "dgCMatrix" [1,] 1 . . . [2,] . 1 . 0.5 [3,] . . 1 .. New Matrix:.. newExampleMatrix 3 x 4 sparse Matrix of class "dgCMatrix" [1,] . 1 . 0.5 [2,] . 1 . 0.5 [3,] . 1 . 0.5 When I try the following I get a memory allocation error due to the size of the array or vector: newExampleMatrix<-Matrix(rep(exampleMatrix[2,],times=nrow (exampleMatrix)),nrow=nrow(exampleMatrix),ncol=ncol (exampleMatrix),byrow=TRUE,sparse=TRUE) newExampleMatrix<-Matrix(exampleMatrix[2,],nrow=nrow (exampleMatrix),ncol=ncol(exampleMatrix),byrow=TRUE,sparse=TRUE) When I tried the next set, I got the error "Error in Matrix(as(rep (exampleMatrix[2, ], times = nrow(exampleMatrix)), : invalid type/length (S4/12) in vector allocation": newExampleMatrix<-Matrix(as(rep(exampleMatrix[2,],times=nrow (exampleMatrix)),"sparseVector"),nrow=nrow(exampleMatrix),ncol=ncol (exampleMatrix),byrow=TRUE,sparse=TRUE) newExampleMatrix<-Matrix(as(exampleMatrix[2,],"sparseVector"),nrow=nrow (exampleMatrix),ncol=ncol(exampleMatrix),byrow=TRUE,sparse=TRUE) And finally, when I tried the next instruction, I got the error "Error in as.vector(x, mode) : cannot coerce type 'S4' to vector of type 'any' Error in as.matrix.csc(as.matrix.csr(x)) : error in evaluating the argument 'x' in selecting a method for function 'as.matrix.csc'" : as.matrix.csc(as(rep(currentMatrix[pivitRow,],times=nrow (currentMatrix)),"sparseVector"),nrow=nrow(currentMatrix),ncol=ncol (currentMatrix)) Are there any other ways to accomplish this?], Thanks, Brian Notice: This communication is an electronic communication within the meaning of the Electronic Communications Privacy Act, 18 U.S.C. sec. 2510. Its disclosure is strictly limited to the recipient(s) intended by the sender of this message. This transmission and any attachments may contain proprietary, confidential, attorney-client privileged information and/or attorney work product. If you are not the intended recipient, any disclosure, copying, distribution, reliance on, or use of any of the information contained herein is STRICTLY PROHIBITED. Please destroy the original transmission and its attachments without reading or saving in any matter and confirm by return email.
>>>>> "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