在大稀疏矩阵中交换值

时间:2017-09-15 12:01:51

标签: r matrix sparse-matrix swap

我有一个非常大的稀疏矩阵,所以我需要快速解决我的问题:

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并找出我需要它的原因。

1 个答案:

答案 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