Search code examples
rmatrixsparse-matrix

Efficiently setting elements of a sparse matrix to 0


Say I have a sparse matrix:

library(Matrix)
m <- Matrix(rpois(100, 1), 10, 10, sparse=TRUE)
m
#10 x 10 sparse Matrix of class "dgCMatrix"

# [1,] . . 2 3 1 1 1 . 3 1
# [2,] 1 . 1 . 1 . 2 . . .
# [3,] 1 4 1 . . . . 5 1 1
# [4,] . 1 1 . . . 4 1 1 1
# [5,] 1 . 4 . 1 . . 1 . 2
# [6,] 1 1 2 1 . 1 . 1 2 1
# [7,] 4 2 1 1 . . . 1 1 3
# [8,] 2 2 1 1 1 1 . 1 1 2
# [9,] 2 1 1 . 3 . 2 . . 1
#[10,] . 2 1 1 . . . 1 3 3

I want to set all elements to zero, that are less than or equal to 1. Is this a safe way of doing it? Note that m2 isn't technically a compressed sparse matrix any more, since some of the "nonzero" elements are now actually zero.

m2@x[m2@x < 2] <- 0
m2
#10 x 10 sparse Matrix of class "dgCMatrix"

# [1,] . . 2 3 0 0 0 . 3 0
# [2,] 0 . 0 . 0 . 2 . . .
# [3,] 0 4 0 . . . . 5 0 0
# [4,] . 0 0 . . . 4 0 0 0
# [5,] 0 . 4 . 0 . . 0 . 2
# [6,] 0 0 2 0 . 0 . 0 2 0
# [7,] 4 2 0 0 . . . 0 0 3
# [8,] 2 2 0 0 0 0 . 0 0 2
# [9,] 2 0 0 . 3 . 2 . . 0
#[10,] . 2 0 0 . . . 0 3 3

In particular, I don't want to create a massive indicator matrix that gives the locations of the elements to change (as in m[m < 2] <- 0), or loop through the elements manually.


Solution

  • I don't see anything unsafe in your approach and it might even be recommended. If you want to have a fully sparse matrix as a result you can do this:

    drop0(m2)
    #10 x 10 sparse Matrix of class "dgCMatrix"
    #                         
    # [1,] 2 . . . . . . . . .
    # [2,] . . . 2 . . . . . .
    # [3,] . . 2 . . . . . 2 .
    # [4,] 2 2 . . 4 . . 2 2 3
    # [5,] . 4 . 3 . 3 . . . .
    # [6,] 2 . . . . 3 2 . . .
    # [7,] . . . . . . 2 . . 2
    # [8,] . . . . . . 2 . . 4
    # [9,] 2 . . 2 . . . . . 2
    #[10,] . . . . . . 2 . . .