我在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软件包,并最终使用write.matrix.csr()
将此矩阵保存为libsvm格式,因此首先我需要将稀疏矩阵转换为 SparseM 格式
我试着这样做:
library(SparseM)
X2 <- as.matrix.csr(X)
但它很快就会填满我的RAM并最终导致R崩溃。我怀疑在内部,as.matrix.csr
首先将稀疏矩阵转换为不适合我的计算机内存的密集矩阵。
我的另一种选择是直接以SparseM格式创建稀疏矩阵
我尝试了as.matrix.csr(X_factors)
,但它不接受数据框架的因素。
SparseM包中是否有等效的sparse.model.matrix(~.-1, data = X_factors)
?我搜索了文档,但没有找到。
答案 0 :(得分: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