2012-09-29 32 views
2

我有一個從R的Matrix包創建的稀疏矩陣。我想迭代矩陣中的每個條目並執行一個操作,將結果保存在與原始矩陣具有相同索引的另一個稀疏矩陣中。R:映射稀疏矩陣中所有條目的方法

例如,假設我有稀疏矩陣A:

1 . 1 
2 . . 
. . 4 

ColSums會是什麼樣子:

3 . 5 

RowSums會是什麼樣子:

2 
2 
4 

我想迭代A並執行此操作

(1,1) > 3*2 
(2,1) > 2*3 
(1,3) > 2*5 
(3,3) > 4*5 

創建B:

6 . 10 
6 . . 
. . 20 

我怎麼會去一個量化的方式這樣做呢?

我認爲函數foo看起來像:

B=fooMap(A,fun) 

和樂趣會是什麼樣子:

fun(row,col) = RowSums(row) * ColSums(col) 

什麼fooMap?

編輯:

我用flodel的解決方案。它使用匯總將稀疏矩陣轉換爲i,j,x數據幀,然後與&朋友一起使用來對該幀執行操作,然後將結果轉換回稀疏矩陣。使用這種技術,with/within運算符是fooMap;稀疏矩陣必須首先轉換爲i,j,x數據幀,以便可以使用/ within。

這是解決這個特殊問題的單線程。

B = with(summary(A), sparseMatrix(i=i, j=j, x = rowSums(A)[i] * colSums(A)[j])) 

回答

4

每當我有稀疏矩陣元素的運算,我來回走了矩陣本身及其summary表示之間:

summ.B <- summary(A) 
summ.B <- within(summ.B, x <- rowSums(A)[i]*colSums(A)[j]) 
B <- sparseMatrix(i = summ.B$i, j = summ.B$j, x = summ.B$x) 
B 
# 3 x 3 sparse Matrix of class "dgCMatrix" 
#    
# [1,] 6 . 10 
# [2,] 6 . . 
# [3,] . . 20 
+0

+1 - 這是一個好主意。 –

+0

內看起來非常強大。那麼在內部,你已經讀取了對象中所有列的訪問權限,它們的框架名稱被引用了嗎?這是用來構建原始對象的稍微修改版本,但作爲一個新的對象,不共享任何相同的內存,是嗎? –

+0

是的,這是正確的:-) – flodel

2

下面是一個在每一步都使用稀疏矩陣的方法。

## Load library and create example sparse matrix 
library(Matrix) 
m <- sparseMatrix(i = c(1,2,1,3), j = c(1,1,3,3), x = c(1,2,1,4)) 

## Multiply each cell by its respective row and column sums. 
Diagonal(x = rowSums(m)) %*% (1*(m!=0)) %*% Diagonal(x = colSums(m)) 
# 3 x 3 sparse Matrix of class "dgCMatrix" 
#    
# [1,] 6 . 10 
# [2,] 6 . . 
# [3,] . . 20 

(在(1*(m!=0))1*被用來強制類「lgCMatrix」由m!=0產生回數字矩陣類「dgCMatrix」的邏輯矩陣。較長嗦(但也許更清楚)替代方案將到在它的地方使用as(m!=0, "dgCMatrix")

+0

這非常簡潔。我當然可以在映射函數操作符是*的情況下使用它。這絕對是一個非常常見的操作。但我的線性代數經驗並不太好。這種方法是否推廣到其他操作符,比如rowSum + colSum(而不是*)? –

+0

當然你可以這樣做,像這樣:'m2 < - 1 *(m!= 0); (對角線(x = rowSums(m))%*%m2)+(m2%*%對角線(x = colSums(m)))''。但是,直到你對基本矩陣運算有合理的感覺,任意泛化可能是一個挑戰。 –