How to convert a regular matrix to a sparse matrix in R?

老子叫甜甜 提交于 2019-12-11 18:15:09

问题


I have a 200K row x 27K column matrix and I'd like to convert it to a sparse matrix. I've tried doing this, but I get a segmentation fault:

> dim(my_regular)
[1] 196501  26791

> my_sparse <- as(my_regular, "sparseMatrix")

 *** caught segfault ***
address 0x2b9e3e10e000, cause 'memory not mapped'

Is there a better way?


回答1:


This is definitely not ideal, but the only way I could get the conversion to happen was to break up the matrix in groups of 50K rows and then use rbind to combine them:

my_sparse_1 <- Matrix::Matrix(my_regular[1:50000,], sparse = TRUE)
my_sparse_2 <- Matrix::Matrix(my_regular[50001:100000,], sparse = TRUE)
# etc.
my_sparse <- rbind(my_sparse_1, my_sparse_2, etc.)

I won't accept my answer, in case anyone has a better suggestion




回答2:


First of all if as(my_regular, "sparseMatrix") gives segfault - please report to Matrix package maintainer (can be found here https://cran.r-project.org/web/packages/Matrix/index.html).

As a workaround you can use something like this:

library(Matrix)
nc = 50
nr = 100
sparsity = 0.9
m = sample(c(0, 1), size = nr * nc, replace = TRUE, prob = c(sparsity, 1 - sparsity))
m = matrix(m, nr, nc)

# normal way of coercing dense to sparse
spm1 = as(m, "CsparseMatrix")

# get indices of non-zero elements
ind_nnz = which(m != 0)

# construct zero-based indices of row and column
i = (ind_nnz - 1L) %% nr
j = as.integer((ind_nnz - 1L) / nr)
# get non-zero values
x = m[ind_nnz]

spm2 = sparseMatrix(i = i, j = j, x = x, dims = c(nr, nc), index1 = FALSE)

identical(spm1, spm2)
# TRUE


来源:https://stackoverflow.com/questions/48326436/how-to-convert-a-regular-matrix-to-a-sparse-matrix-in-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!