计算稀疏矩阵每列中两个值之间的元素数

Counting number of elements that fall between two values in each column of sparse matrix

我有一个稀疏矩阵,如下图

library(Matrix)

set.seed(2019)
nrows <- 10L
ncols <- 5L
vals <- sample(
  x = c(0,1,2,3),
  prob = c(0.7,0.1,0.1,0.1),
  size = nrows*ncols,
  replace = TRUE
)
mat <- matrix(vals,nrow=nrows)
matSparse <- as(mat,"sparseMatrix")

> matSparse
10 x 5 sparse Matrix of class "dgCMatrix"

 [1,] 2 2 . . .
 [2,] 2 . . . .
 [3,] . . 1 3 3
 [4,] . . . . .
 [5,] . . . . 3
 [6,] . . . . .
 [7,] 3 . . . 1
 [8,] . 2 1 . 1
 [9,] . . . . .
[10,] . . . 2 .

我想为每一列计算落在特定值之间的元素数量(每一列可能不同)。例如,我有一个向量(长度 ncolsbrks = c(1, 2, 1, 2, 2)。我想为每一列 j 计算以下内容:

1) > 0(.)<=brks[j]的元素个数 2) >brks[j].

的元素个数

在上面的示例中,结果将是 1) 0 2 2 1 2 和 2) 3 0 0 1 2

我已经尝试创建 class lgeMatrix 的逻辑稀疏矩阵并应用 colSums,但没有成功。最后我想有一个 高效 方法来做到这一点,因为我有非常大的矩阵(10000 行和 100000 列)

我们可以使用 sapply 遍历每一列和 brks

sapply(seq_len(ncol(matSparse)), function(i) 
                sum(matSparse[, i] > 0 & matSparse[, i] <= brks[i]))
#[1] 0 2 2 1 2

sapply(seq_len(ncol(matSparse)), function(i) sum(matSparse[, i] > brks[i]))
#[1] 3 0 0 1 2

由于在这两个条件下我们都在列上循环,我们还可以结合这两个条件并执行一个 sapply 调用

t(sapply(seq_len(ncol(matSparse)), function(i) 
       c(sum(matSparse[, i] > 0 & matSparse[, i] <= brks[i]), 
         sum(matSparse[, i] > brks[i]))))

#      [,1] [,2]
#[1,]    0    3
#[2,]    2    0
#[3,]    2    0
#[4,]    1    1
#[5,]    2    2

其中第一列是第一个条件的输出,第二列是第二个条件的输出。

如果与相同维度的矩阵进行比较会怎样?

cmpr <- t(brks)[rep(1,nrow(matSparse)),]

colSums(matSparse > 0 & matSparse <= cmpr)
#[1] 0 2 2 1 2

colSums(matSparse > cmpr)
#[1] 3 0 0 1 2

甚至sweep:

gt0ltB <- function(x,y) x > 0 & x <= y
gtB    <- function(x,y) x > y

colSums(sweep(matSparse, STATS=brks, MARGIN=2, FUN=gt0ltB))
#[1] 0 2 2 1 2
colSums(sweep(matSparse, STATS=brks, MARGIN=2, FUN=gtB))
#[1] 3 0 0 1 2