等效于Matrix类的rowum函数(dgCMatrix)

时间:2018-06-25 14:33:27

标签: r matrix sparse-matrix rowsum

对于基本R矩阵类,我们具有rowsum函数,该函数对于计算行组之间的列总和非常快。

在Matrix-package中是否实现了等效的功能或方法?

我对大型dgCMatrix对象(即数百万行,但稀疏程度约为95%)的rowsum的快速替代方案特别感兴趣。

2 个答案:

答案 0 :(得分:0)

我知道这是一个老问题,但是Matrix :: rowSums可能就是您要寻找的功能。

答案 1 :(得分:0)

这是一种使用矩阵乘法的方法,基于 https://slowkow.com/notes/sparse-matrix/ 中的示例。首先,让我们创建一个稀疏矩阵来玩,

library(magrittr)
library(forcats)
library(stringr)
library(Matrix)

set.seed(42)
m <- sparseMatrix(
  i = sample(x = 1e4, size = 1e4),
  j = sample(x = 1e4, size = 1e4),
  x = rnorm(n = 1e4)
)
colnames(m) <- str_c("col", seq(ncol(m)))
rownames(m) <- str_c("row", seq(nrow(m)))

以及定义要求和的行的分组向量,

group <- sample(1:10, nrow(m), replace = TRUE) %>%
  paste0("new_row", .) %>%
  fct_inorder

group 是否是一个因子,其层序会影响合并矩阵中最终的行序。我将 group 作为一个因子,其级别按 group 中的首次出现排序,以使行顺序类似于 rowsum()reorder = FALSE 操作。

接下来,我们创建一个(稀疏)矩阵,我们可以将其左乘 m 以获得 m 的版本,其行已基于 group 求和,

group_mat <- sparse.model.matrix(~ 0 + group) %>% t
# Adjust row names to get the correct final row names
rownames(group_mat) <- rownames(group_mat) %>% str_extract("(?<=^group).+")

msum <- group_mat %*% m  

结果与矩阵的密集版本上的 base::rowsum() 匹配,

d <- as.matrix(m)
dsum <- rowsum(d, group, reorder = FALSE)
all.equal(as.matrix(msum), dsum)
#> [1] TRUE

但稀疏矩阵乘法方法要快得多,

bench::mark( msum <- group_mat %*% m )$median
#> [1] 344µs
bench::mark( dsum <- rowsum(d, group) )$median
#> [1] 146ms