对于基本R矩阵类,我们具有rowsum
函数,该函数对于计算行组之间的列总和非常快。
在Matrix-package中是否实现了等效的功能或方法?
我对大型dgCMatrix对象(即数百万行,但稀疏程度约为95%)的rowsum
的快速替代方案特别感兴趣。
答案 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