2012-09-29 29 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)))''。但是,直到你对基本矩阵运算有合理的感觉,任意泛化可能是一个挑战。 –