我有一个非常大的稀疏矩阵,所以我需要快速解决我的问题:
让A
成为一个小的稀疏矩阵(例如):
> A
4 x 5 sparse Matrix of class "dgCMatrix"
A B C D E
[1,] 1 1 5 4 6
[2,] 51 2 40 1 5
[3,] 3 40 10 . 50
[4,] . 6 3 . 30
> dput(A)
new("dgCMatrix"
, i = c(0L, 1L, 2L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 3L, 0L, 1L, 0L, 1L,
2L, 3L)
, p = c(0L, 3L, 7L, 11L, 13L, 17L)
, Dim = 4:5
, Dimnames = list(NULL, c("A", "B", "C", "D", "E"))
, x = c(1, 51, 3, 1, 2, 40, 6, 5, 40, 10, 3, 4, 1, 6, 5, 50, 30)
, factors = list()
)
我需要的是第一行值==列位置。像这样:
A B C D E
[1,] 1 2 3 4 5
[2,] 51 1 40 1 6
[3,] 3 40 10 . 50
[4,] . 6 5 . 30
所以我想要的是交换值。在这个例子中,我想交换:
A[1,2]
和A[2,2]
A[1,3]
和A[4,3]
A[1,5]
和A[2,5]
但我有一个非常大的稀疏矩阵,所以我必须首先找到A[1,i] != i
的位置,然后找到行which(A[,i] == i)
并交换它们。
我试过了:
ROW <- A[1,]
for (i in 1:ncol(ROW)){
if (ROW[i] != i){
a <- ROW[i]
b <- A[which(A[,i] == i), i]
p <- which(A[,i] == i)
A[1,i] <- b
A[p,i] <- a
}
}
它有效,但它真的很慢。我使用的原始矩阵有28182行和28182列。
如何改进我的方法?
请不要问我为什么要做这个奇怪的事情。我只是需要它。您还可以查看here并找出我需要它的原因。
答案 0 :(得分:0)
如果你使用&#34; dgTMatrix&#34;会更容易,其中矩阵由三个向量(i, j, x)
表示,它对应于行id,col id和单元格值。
您可以直接使用这些矢量进行交换操作。
library(Matrix)
A <- new("dgCMatrix"
, i = c(0L, 1L, 2L, 0L, 1L, 2L, 3L, 0L, 1L, 2L, 3L, 0L, 1L, 0L, 1L,
2L, 3L)
, p = c(0L, 3L, 7L, 11L, 13L, 17L)
, Dim = 4:5
, Dimnames = list(NULL, c("A", "B", "C", "D", "E"))
, x = c(1, 51, 3, 1, 2, 40, 6, 5, 40, 10, 3, 4, 1, 6, 5, 50, 30)
, factors = list()
)
B <- as(A, "dgTMatrix")
flg1 <- (B@i == 0) & (B@j != (B@x-1)) # corresponds to `i`
val1 <- B@x[flg1] # corresponds to `a`
col1 <- B@j[flg1]
flg2 <- (B@j %in% col1) & (B@j == (B@x-1)) # corresponds to `p`
val2 <- B@x[flg2] # corresponds to `b`
B@x[flg1] <- val2
B@x[flg2] <- val1
B