将巨大的稀疏矩阵转换为data.table,以便在R中更快地进行子集划分

将巨大的稀疏矩阵转换为data.table,以便在R中更快地进行子集划分,r,dataframe,data.table,tm,R,Dataframe,Data.table,Tm,我有一个大问题,一个更具体的问题,我希望这个问题一旦解决,就能解决更大的问题。如果有人有任何想法让我尝试,我会非常感激 基本上,我有一个巨大的稀疏矩阵(大约300k x 150k,最初是用R的{tm}包创建的术语文档矩阵),它使用{slam}包保存为一个简单的三元组矩阵,我正在运行一个函数,该函数循环遍历术语集,然后根据这些术语对其进行子集划分。不幸的是,细分过程非常缓慢 在试图找出如何更快地进行子集时,我偶然发现了data.table包,它在我使用它运行的一些测试中表现得非常好。然而,当我尝试

我有一个大问题,一个更具体的问题,我希望这个问题一旦解决,就能解决更大的问题。如果有人有任何想法让我尝试,我会非常感激

基本上,我有一个巨大的稀疏矩阵(大约300k x 150k,最初是用R的{tm}包创建的术语文档矩阵),它使用{slam}包保存为一个简单的三元组矩阵,我正在运行一个函数,该函数循环遍历术语集,然后根据这些术语对其进行子集划分。不幸的是,细分过程非常缓慢

在试图找出如何更快地进行子集时,我偶然发现了data.table包,它在我使用它运行的一些测试中表现得非常好。然而,当我尝试将稀疏矩阵转换为data.table时,我得到

Error in vector(typeof(x$v), nr * nc) : vector size cannot be NA
In addition: Warning message:
In nr * nc : NAs produced by integer overflow
我理解这是因为它首先尝试将其转换为标准矩阵,这在技术上是R的向量,300k*150k远高于
.Machine$integer.max

所以我的问题是:有人知道如何将简单的三元组矩阵转换为data.frame或data.table,而不首先将其转换为矩阵,从而避免整数溢出吗

如果没有,是否有人a)有其他解决方法或b)有关于快速子集巨大稀疏矩阵和/或简单三重矩阵的建议

下面是一个可重复的例子。在我的机器上,循环将前10行中的每一行子集化,大约需要3秒。一旦我们进入数十万行的循环,这很快就会让人望而却步。提前感谢您的帮助:

require(slam)
STM <- simple_triplet_matrix(i = as.integer(runif(10000000,1,300000)), 
                  j = as.integer(runif(10000000,1,150000)),
                  v = rep(rnorm(10), 1000000),
                  nrow = 300000,
                  ncol = 150000)

start <- Sys.time()
for (i in 1:10) {
  vec <- as.matrix(STM[,i])
}
Sys.time() - start
require(slam)

STMSTM对象实际上只是一个列表,您可以正常子集:


STM_DTSTM对象实际上只是一个列表,您可以正常地子集:


STM_DT您很可能需要这样的东西

这个例子最初是为了解决一个更具体的问题,即如何将稀疏(但巨大)的模型矩阵附加到数据表中

稀疏矩阵示例:

5 x 8 sparse Matrix of class "dgCMatrix"
  X1a X1b X1c X1d X2b X2c X3b X3c
1   .   1   .   .   1   .   1   .
2   1   .   .   .   .   .   .   1
3   .   .   .   1   .   1   .   1
4   .   .   1   .   .   1   .   .
5   1   .   .   .   1   .   .   .

print(object.size(mat))
3760字节

具有以下属性:

mat@i # 0-based row index
[1] 143020423012

mat@p # 0-based column start
[1] 0234579102

以下是如何转换为数据表:

# Conversion to Data Table
dt = data.table::data.table(matrix(FALSE,nrow(mat),ncol(mat)))
setnames(dt,colnames(mat))

for(cStart in 1:ncol(mat))
  set(dt, i = mat@i[(mat@p[cStart]:(mat@p[cStart+1L]-1L))+1L]+1L, 
j=colnames(mat)[cStart], value=TRUE)

print(object.size(dt))
2696字节

dt[,lapply(.SD, as.integer)]
返回所需的:

   X1a X1b X1c X1d X2b X2c X3b X3c
1:   0   1   0   0   1   0   1   0
2:   1   0   0   0   0   0   0   1
3:   0   0   0   1   0   1   0   1
4:   0   0   1   0   0   1   0   0
5:   1   0   0   0   1   0   0   0

很可能你需要这样的东西

这个例子最初是为了解决一个更具体的问题,即如何将稀疏(但巨大)的模型矩阵附加到数据表中

稀疏矩阵示例:

5 x 8 sparse Matrix of class "dgCMatrix"
  X1a X1b X1c X1d X2b X2c X3b X3c
1   .   1   .   .   1   .   1   .
2   1   .   .   .   .   .   .   1
3   .   .   .   1   .   1   .   1
4   .   .   1   .   .   1   .   .
5   1   .   .   .   1   .   .   .

print(object.size(mat))
3760字节

具有以下属性:

mat@i # 0-based row index
[1] 143020423012

mat@p # 0-based column start
[1] 0234579102

以下是如何转换为数据表:

# Conversion to Data Table
dt = data.table::data.table(matrix(FALSE,nrow(mat),ncol(mat)))
setnames(dt,colnames(mat))

for(cStart in 1:ncol(mat))
  set(dt, i = mat@i[(mat@p[cStart]:(mat@p[cStart+1L]-1L))+1L]+1L, 
j=colnames(mat)[cStart], value=TRUE)

print(object.size(dt))
2696字节

dt[,lapply(.SD, as.integer)]
返回所需的:

   X1a X1b X1c X1d X2b X2c X3b X3c
1:   0   1   0   0   1   0   1   0
2:   1   0   0   0   0   0   0   1
3:   0   0   0   1   0   1   0   1
4:   0   0   1   0   0   1   0   0
5:   1   0   0   0   1   0   0   0

三重矩阵本质上是3个向量,包含前2列中非零元素的坐标和第3列中的值。一种可能的方法(我没有测试)是使用RCPP包来编写C++中的子设置算法,将三重集传递给C++作为3个向量的列表。三重矩阵基本上是3个向量,在前2列中包含非零元素的坐标,在第3列中包含值。一种可能的方法(我没有测试)是使用RCPP包来编写C++中的子设置算法,将三重集传递给C++作为3个向量的列表。应该尽可能快地在R做任何事情。谢谢。太好了,谢谢你。太好了。