繁体   English   中英

一种快速排列稀疏矩阵中每一列的方法

[英]A fast way to rank each column in a sparse matrix

我有一个dgCMatrix稀疏矩阵:

library(Matrix)
set.seed(1)
mat <- Matrix(c(0,0,2:0), 3,5)
rownames(mat) <- paste0("g",1:3)
colnames(mat) <- paste0("c",1:5)

我想以dplyr::dense_rank()的方式对每一列进行降序排列,这样领带就会获得相同的排名,没有差距。

我正在寻找的 output 是一个data.frame ,其中每一行都有matcolnamesrownamesrank s。

我目前正在使用这个do.call function:

library(dplyr)
df <- do.call(rbind,lapply(1:ncol(mat),function(x){
  data.frame(cell=colnames(mat)[x],gene_name = rownames(mat),value=mat[,x]) %>%
    dplyr::arrange(desc(value)) %>%
    dplyr::mutate(rank=dplyr::dense_rank(desc(value)))
}))

但是寻找更快的东西。 我知道我的问题与这篇文章类似但不完全相同,因为这篇文章中使用的split不保留rownames

CsparseMatrixTsparseMatrix并对结果进行操作在这里可能是最自然的:

library(Matrix)
set.seed(0)
m <- 6L
n <- 6L
x <- rsparsematrix(m, n, 0.5, rand.x = function(n) trunc(rnorm(n, 0, 2)))
dimnames(x) <- list(paste0("r", seq_len(m)), paste0("c", seq_len(n)))
x
6 x 6 sparse Matrix of class "dgCMatrix"
   c1 c2 c3 c4 c5 c6
r1  0 -1  . -2  .  1
r2  .  . -1  .  0  .
r3  . -2  .  0  0  .
r4 -2  1  .  0  .  0
r5  .  0  .  0  .  .
r6  .  . -1  2  .  0
denseRank <- function(x, ...) match(x, sort(unique(x), ...))
y <- as(x, "TsparseMatrix")
d <- data.frame(row = y@Dimnames[[1L]][y@i+1L],
                col = y@Dimnames[[2L]][y@j+1L],
                val = y@x,
                ran = unsplit(lapply(split(y@x, y@j), denseRank, decreasing = TRUE, na.last = NA), y@j))
d
   row col val ran
1   r1  c1   0   1
2   r4  c1  -2   2
3   r1  c2  -1   3
4   r3  c2  -2   4
5   r4  c2   1   1
6   r5  c2   0   2
7   r2  c3  -1   1
8   r6  c3  -1   1
9   r1  c4  -2   3
10  r3  c4   0   2
11  r4  c4   0   2
12  r5  c4   0   2
13  r6  c4   2   1
14  r2  c5   0   1
15  r3  c5   0   1
16  r1  c6   1   1
17  r4  c6   0   2
18  r6  c6   0   2
z <- y
z@x <- as.double(d$ran)
z
6 x 6 sparse Matrix of class "dgTMatrix"
   c1 c2 c3 c4 c5 c6
r1  1  3  .  3  .  1
r2  .  .  1  .  1  .
r3  .  4  .  2  1  .
r4  2  1  .  2  .  2
r5  .  2  .  2  .  .
r6  .  .  1  1  .  2

如果矩阵包含NA ,则需要小心。 以上将na.last = NA传递给denseRank ,以便NA值获得NA排名; 这与dplyr::dense_rank一致。 如果您希望为NA值分配最低或最高等级,则必须分别传递na.last = FALSEna.last = TRUE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM