对于基本的 R 矩阵类,我们有一个rowsum
函数,它可以非常快地计算跨行组的列和。
Matrix-package 中是否实现了等效的功能或方法?
我rowsum
对大型 dgCMatrix 对象(即数百万行,但大约 95% 稀疏)的快速替代方案特别感兴趣。
对于基本的 R 矩阵类,我们有一个rowsum
函数,它可以非常快地计算跨行组的列和。
Matrix-package 中是否实现了等效的功能或方法?
我rowsum
对大型 dgCMatrix 对象(即数百万行,但大约 95% 稀疏)的快速替代方案特别感兴趣。
我知道这是一个老问题,但Matrix::rowSums
可能是您正在寻找的功能。
DelayedArray BioConductor包现在有一个 rowsum 函数,它接受稀疏矩阵,当我尝试它时,它的速度非常快。
这是一种使用矩阵乘法的方法,基于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