2

对于基本的 R 矩阵类,我们有一个rowsum函数,它可以非常快地计算跨行组的列和。

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

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

4

3 回答 3

5

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

于 2018-11-26T20:06:41.593 回答
0

DelayedArray BioConductor包现在有一个 rowsum 函数,它接受稀疏矩阵,当我尝试它时,它的速度非常快。

于 2021-10-15T07:18:36.107 回答
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
于 2021-03-09T00:26:22.953 回答