14

我在 R 中有一个因子矩阵,并希望将其转换为每个因子的所有可能级别的虚拟变量 0-1 矩阵。

然而,这个“虚拟”矩阵非常大(91690x16593)并且非常稀疏。我需要将它存储在一个稀疏矩阵中,否则它不适合我的 12GB 内存。

目前,我正在使用以下代码,它工作得很好,需要几秒钟:

library(Matrix)
X_factors <- data.frame(lapply(my_matrix, as.factor))
#encode factor data in a sparse matrix
X <- sparse.model.matrix(~.-1, data = X_factors)

但是,我想在 R 中使用 e1071 包,并最终将此矩阵保存为 libsvm 格式write.matrix.csr(),所以首先我需要将我的稀疏矩阵转换为SparseM格式。

我试着做:

library(SparseM)  
X2 <- as.matrix.csr(X)

但它很快就填满了我的 RAM,最终 R 崩溃了。我怀疑在内部,as.matrix.csr首先将稀疏矩阵转换为不适合我的计算机内存的密集矩阵。

我的另一种选择是直接以 SparseM 格式创建我的稀疏矩阵。
我试过as.matrix.csr(X_factors)了,但它不接受因子的数据框。

sparse.model.matrix(~.-1, data = X_factors)SparseM 包中是否有等价物?我在文档中搜索但没有找到。

4

1 回答 1

20

相当棘手,但我想我明白了。

让我们从Matrix包中的稀疏矩阵开始:

i <- c(1,3:8)
j <- c(2,9,6:10)
x <- 7 * (1:7)
X <- sparseMatrix(i, j, x = x)

Matrix包使用面向列的压缩格式,同时SparseM支持面向列和面向行的格式,并具有可以轻松处理从一种格式转换为另一种格式的功能。

因此,我们首先将面向列的矩阵转换为面向Matrix列的SparseM矩阵:我们只需要小心调用正确的构造函数并注意两个包对索引使用不同的约定(从0或开始1):

X.csc <- new("matrix.csc", ra = X@x,
                           ja = X@i + 1L,
                           ia = X@p + 1L,
                           dimension = X@Dim)

然后,从面向列的格式更改为面向行的格式:

X.csr <- as.matrix.csr(X.csc)

你完成了!您可以通过执行以下操作检查两个矩阵是否相同(在我的小示例中):

range(as.matrix(X) - as.matrix(X.csc))
# [1] 0 0
于 2013-06-29T01:16:08.893 回答