【问题标题】:Counting number of elements that fall between two values in each column of sparse matrix计算稀疏矩阵每列中两个值之间的元素数
【发布时间】:2019-07-15 03:28:26
【问题描述】:

我有一个稀疏矩阵,如下所示

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) &gt; 0(.)&lt;=brks[j] 的元素数量 2) &gt;brks[j]的元素个数。

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

我尝试创建 lgeMatrix 类的逻辑稀疏矩阵并应用 colSums,但没有成功。最后,我想要一种高效的方法,因为我有非常大的矩阵(10000 行和100000 列)

【问题讨论】:

    标签: r sparse-matrix


    【解决方案1】:

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

    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
    

    【讨论】:

      【解决方案2】:

      我们可以使用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
      

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

      【讨论】:

      • 抱歉,我在您发布答案之前编辑了帖子。
      • 谢谢,我考虑过循环和apply 系列函数,但这对我的应用程序来说太慢了。我正在尝试利用数据集的稀疏特性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-27
      • 2017-01-13
      • 2020-03-09
      • 1970-01-01
      • 2017-04-16
      • 2014-10-11
      相关资源
      最近更新 更多