Search code examples
rvectorizationsparse-matrix

R: Way to map over all entries in a sparse matrix


I have a sparse matrix created from R's Matrix package. I would like to iterate over each entry in the matrix and perform an operation, saving the result in another sparse matrix with the same indexes as the original matrix.

For example, let's say I have sparse matrix A:

1 . 1
2 . .
. . 4

ColSums would look like:

3 . 5

RowSums would look like:

2
2
4

I would like to iterate over A and do this

(1,1) > 3*2
(2,1) > 2*3
(1,3) > 2*5
(3,3) > 4*5

Creating B:

6 . 10
6 . .
. . 20

How would I go about doing this in a vectorized way?

I would think the function foo would look like:

B=fooMap(A,fun)

And fun would look like:

fun(row,col) = RowSums(row) * ColSums(col)

What's fooMap?

EDIT:

I went with flodel's solution. It uses summary to convert the sparse matrix into an i,j,x data frame, then uses with & friends to perform an operation on that frame, and then turns the result back into a sparse matrix. With this technique, the with/within operator is fooMap; the sparse matrix just has to be converted into the i,j,x data frame first so that with/within can be used.

Here's a one-liner that solved this particular problem.

B = with(summary(A), sparseMatrix(i=i, j=j, x = rowSums(A)[i] * colSums(A)[j]))

Solution

  • Whenever I have element-wise operations on sparse matrices, I go back and forth between the matrix itself and its summary representation:

    summ.B <- summary(A)
    summ.B <- within(summ.B, x <- rowSums(A)[i]*colSums(A)[j])
    B <- sparseMatrix(i = summ.B$i, j = summ.B$j, x = summ.B$x)
    B
    # 3 x 3 sparse Matrix of class "dgCMatrix"
    #            
    # [1,] 6 . 10
    # [2,] 6 .  .
    # [3,] . . 20