2017-09-15 195 views
0

我有一個非常大的稀疏矩陣,所以我需要我的問題的一些快速的解決方案:交換價值

讓我們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

在你的代碼中,'p​​'可能包含多個位置。你會在這種情況下做什麼? –

+0

@KotaMori這不可能發生。 「A」列中的值是產品ID,一個產品在一列中只能有一次。 –

回答

0

如果您使用「dgTMatrix」,其中矩陣由三個向量(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 <- ([email protected] == 0) & ([email protected] != ([email protected])) # corresponds to `i` 
val1 <- [email protected][flg1] # corresponds to `a` 
col1 <- [email protected][flg1] 

flg2 <- ([email protected] %in% col1) & ([email protected] == ([email protected])) # corresponds to `p` 
val2 <- [email protected][flg2] # corresponds to `b` 

[email protected][flg1] <- val2 
[email protected][flg2] <- val1 

B