views:

831

answers:

2

After learning about the options for working with sparse matrices in R, I want to use the Matrix package to create a sparse matrix from the following data frame and have all other elements be NA.

     s    r d
1 1089 3772 1
2 1109  190 1
3 1109 2460 1
4 1109 3071 2
5 1109 3618 1
6 1109   38 7

I know I can create a sparse matrix with the following, accessing elements as usual:

> library(Matrix)
> Y <- sparseMatrix(s,r,x=d)
> Y[1089,3772]
[1] 1
> Y[1,1]
[1] 0

but if I want to have the default value to be NA, I tried the following:

  M <- Matrix(NA,max(s),max(r),sparse=TRUE)
  for (i in 1:nrow(X))
    M[s[i],r[i]] <- d[i]

and got this error

Error in checkSlotAssignment(object, name, value) : 
  assignment of an object of class "numeric" is not valid for slot "x" in an object of class "lgCMatrix"; is(value, "logical") is not TRUE

Not only that, I find that one takes much longer to access to elements.

> system.time(Y[3,3])
   user  system elapsed 
  0.000   0.000   0.003 
> system.time(M[3,3])
   user  system elapsed 
  0.660   0.032   0.995

How should I be creating this matrix? Why is one matrix so much slower to work with?

Here's the code snippet for the above data:

X <- structure(list(s = c(1089, 1109, 1109, 1109, 1109, 1109), r = c(3772, 
190, 2460, 3071, 3618, 38), d = c(1, 1, 1, 2, 1, 7)), .Names = c("s", 
"r", "d"), row.names = c(NA, 6L), class = "data.frame")
+3  A: 

Why do you want default NA values? As far as I know matrices are only sparse if they have zero-cells. As NA is a non-zero value, you loose all the benefits from the sparse matrix. A classic matrix is even more efficient if the matrix has hardly any zeros. A classic matrix is like a vector that will be cut according to the dimensions. So it only has to store the data vector and the dimensions. The sparse matrix stores only the non-zero values, but also stores there location. This is an advantage if and only if you have enough zero values.

Thierry
Yeah, I suppose that's true.
Christopher DuBois
+2  A: 

Yes, Thierry's answer is definitely true I can say as co-author of the 'Matrix' package...

To your other question: Why is accessing "M" slower than "Y"? The main answer is that "M" is much much sparser than "Y" hence much smaller and -- depending on the sizes envolved and the RAM of your platform -- the access time is faster for much smaller objects, notably for indexing into them.

Martin Mächler
Thanks! I look forward to seeing more of your answers on StackOverflow. I'll try and drum up some of the questions I've had while using Matrix...
Christopher DuBois
It is unfortunate that all non-zero cells are always stored. It would be nice to be able to specify a default value other than zero for a sparseMatrix.
Quantum7