Reputation: 6314
I have a symmetric sparse matrix, initialized to zero:
library(Matrix)
set.seed(1)
mat <- Matrix(0,5,5)
Then I have a matrix (idx.mat
) which specifies for each row in mat
, three column indices which should be filled with values given by another matrix (val.mat
):
idx.mat <- do.call(rbind,lapply(1:5,function(i) sample(1:5,3,replace=F)))
val.mat <- matrix(runif(15,1,10),5,3)
So I'm wondering if there's a faster way to populate mat
according to idx.mat
and val.mat
than:
mat <- do.call(rbind,lapply(1:nrow(mat),function(i) {
mat[i,idx.mat[i,]] <- val.mat[i,]
return(mat[i,])
}))
Upvotes: 0
Views: 62
Reputation: 50678
You can also define and declare a sparseMatrix
right from the start.
# Index/value dataframe
df.idx <- cbind.data.frame(
melt(idx.mat)[, -2],
melt(val.mat)[, "value"]);
names(df.idx) <- c("i", "j", "x");
# Declare and define sparseMatrix
mat <- sparseMatrix(i = df.idx$i, j = df.idx$j, x = df.idx$x);
mat;
#5 x 5 sparse Matrix of class "dgCMatrix"
#
#[1,] . 5.479293 . 4.475027 9.412347
#[2,] 2.909283 . 1.120513 . 7.458567
#[3,] . 4.441492 6.865064 . 9.927155
#[4,] 4.420317 . . 8.827218 2.129996
#[5,] . 3.404986 4.063141 7.997007 .
Or without the melt
+df.idx
detour:
i <- rep(seq(1:nrow(idx.mat)), ncol(idx.mat));
j <- c(idx.mat);
x <- c(val.mat);
mat <- sparseMatrix(i = i, j = j, x = x);
#5 x 5 sparse Matrix of class "dgCMatrix"
#
#[1,] . 5.479293 . 4.475027 9.412347
#[2,] 2.909283 . 1.120513 . 7.458567
#[3,] . 4.441492 6.865064 . 9.927155
#[4,] 4.420317 . . 8.827218 2.129996
#[5,] . 3.404986 4.063141 7.997007 .
Upvotes: 1
Reputation: 145775
A better way is to convert your idx.mat
to n x 2 matrix where the columns correspond to row and column indices:
idx = cbind(rep(1:nrow(idx.mat), ncol(idx.mat)), c(idx.mat))
Then you can use that matrix to index and just assign:
mat[idx] = c(val.mat)
mat
# 5 x 5 sparse Matrix of class "dgCMatrix"
#
# [1,] . 5.479293 . 4.475027 9.412347
# [2,] 2.909283 . 1.120513 . 7.458567
# [3,] . 4.441492 6.865064 . 9.927155
# [4,] 4.420317 . . 8.827218 2.129996
# [5,] . 3.404986 4.063141 7.997007 .
Upvotes: 1