1
votes

In my code, the outer function outputs a matrix. Is it possible to make that output sparse matrix? I could convert this output matrix to a sparse matrix, but I want to do something like outer(......, sparse=T) rather than first have the dense matrix then conversion. Because I have very large data. My code and short sample vectors are below. I have read all the related posts but can`t figure it out.

# myvec is a vector of length 100. 
# mycol is a column vector of length 10.

myvec <- c( 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 1, 0, 2, 1, 2, 1, 3, 2, 2, 1, 0, 1, 2, 1, 0, 2, 1, 2, 1, 3, 2, 2, 1, 0,1, 
          2, 2, 3, 1, 2, 1, 0, 2, 1, 2, 1,0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 1, 0, 2, 1, 2, 1, 3, 2, 2, 1, 0, 1, 2,
          1, 0, 2, 1, 2, 1, 3, 2, 2, 1, 0,1, 2, 2, 3, 1, 2, 1, 0, 2, 1, 2, 1,0, 1, 1, 2, 1, 2, 2, 3)


mycol <- c(-15.07,-7.64, -15.48, -18.59, -12.35, -10.44, -11.45, -18.49, -15.24, -13.23)   
 
res <- outer(1:length(mycol), 1:length(mycol), function(i,j) {
               ifelse(myvec > 1, 0, 
                 ifelse(myvec == 1, (mycol[j]-mycol[i])/(1-exp(-(mycol[j]-mycol[i]))), 
                   ifelse(myvec ==0, 1, myvec)))})

I have also tried to create a sparse matrix from scratch using row, col, value triplets, my code is below. But because the entry (resvec) length is 100, the sparse matrix is created but only using the first 10 of the entries to the diagonals and the rest of the off-diagonal elements are zero. But I wanted to write all 100 entries to their locations.

Many thanks in advance.

resvec<- as.vector(res)

matSparse <- sparseMatrix(
  i = 1:length(mycol), 
  j = 1:length(mycol), 
  x = resvec,
  dims = c(length(mycol),length(mycol)), 
  dimnames = list(rownames,colnames)
)

ps: row names and column names are the same.

1
I just edited, thankskutlus
Does this answer your question? sparse outer product in R?John Coleman
Thanks for the link, but it didn`t help me.kutlus

1 Answers

1
votes

Something like this, where I'm just redoing what outer does but just for the myvec values which produce non-zero results. You could simplify the function f a bit, and perhaps make it a function of myvec too.

f <- function(i,j) {
  ifelse(myvec > 1, 0, 
    ifelse(myvec == 1, (mycol[j]-mycol[i])/(1-exp(-(mycol[j]-mycol[i]))), 
      ifelse(myvec ==0, 1, myvec)))}

library(Matrix)
i <- rep(1:length(mycol), times = length(mycol))[myvec < 2]
j <- rep(1:length(mycol), each = length(mycol))[myvec < 2]
myvec <- myvec[myvec < 2]
sparseMatrix(i, j, x = f(i, j))
#> 10 x 10 sparse Matrix of class "dgCMatrix"
#>                                                                                                                 
#>  [1,] 1.000000000  7.434410 1.000000000 .          2.9118151 4.675609 .          1.0000000 0.91740717 .         
#>  [2,] 0.004409999  1.000000 0.003087581 .          1.0000000 .        0.08629586 .         .          0.02095708
#>  [3,] 1.218969243  .        .           0.14518433 .         .        .          0.1560604 .          1.00000000
#>  [4,] .           10.950192 3.255184331 1.00000000 6.2521909 .        .          .         .          5.38531586
#>  [5,] 0.191815105  .        1.000000000 0.01219087 .         2.241996 .          0.0132598 0.17006693 0.62371549
#>  [6,] .            2.981293 .           .          0.3319956 .        0.57859728 .         .          .         
#>  [7,] .            .        0.072926774 .          1.0000000 1.588597 1.00000000 .         0.08761709 0.36106528
#>  [8,] .            .        .           .          6.1532598 1.000000 7.04617334 .         1.00000000 .         
#>  [9,] 1.087407174  .        0.884795398 0.12180607 3.0600669 .        .          0.1310995 .          .         
#> [10,] .            5.610957 .           .          .         2.972579 2.14106528 1.0000000 0.31098581 .