簡體   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