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

set*_*127 2 r dataframe tm 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
Run Code Online (Sandbox Code Playgroud)

我明白这是因为它首先尝试将其转换为标准矩阵,从技术上讲,这是 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
Run Code Online (Sandbox Code Playgroud)

旁注:请注意,如果您尝试STMm <- as.matrix(STM),您会得到与上面显示的相同的溢出错误。

Chr*_*ris 5

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

STM_DT <- data.table(i = STM$i, j = STM$j, v = STM$v)

这给出:

> STM_DT
               i      j           v
       1: 186598    756  0.34271080
       2: 278329  72334  2.03924976
       3: 178388  32708  1.03925605
       4: 260635 101424  0.05780086
       5: 169321 126202  1.00027529
      ---                          
 9999996:  96209  90019 -1.09341023
 9999997:  54467  16612 -2.08070273
 9999998: 179029  96906 -0.86197333
 9999999: 153017 148731  0.47765003
10000000: 104145 123291  0.24258613
Run Code Online (Sandbox Code Playgroud)

速度几乎是瞬时的