# [R] column permutation of sparse matrix

Douglas Bates bates at stat.wisc.edu
Tue Dec 20 16:57:30 CET 2011

```On Tue, Dec 20, 2011 at 8:20 AM, Jean V Adams <jvadams at usgs.gov> wrote:

Hi Jean,

> khai wrote on 12/19/2011 11:26:55 PM:
>
>> Hi,
>>
>> I'm very new to working with sparse matrices and would like to know how
> I
>> can column permute a sparse matrix. Here is a small example:
>>
>> > M1 <-
>> > spMatrix(nrow=5,ncol=6,i=sample(5,15,replace=TRUE),j=sample(6,
>> 15,replace=TRUE),x=round_any(rnorm(15,2),0.001))
>> > M1
>> 5 x 6 sparse Matrix of class "dgTMatrix"
>>
>> [1,] 2.983      .     1.656    5.003    .        .
>> [2,]    .            .     2.990        .         .        .
>> [3,]    .     0.592   5.349    1.115    .        .
>> [4,] 1.836      .     2.804        .         .        .
>> [5,]    .     6.961       .             .         .     1.077
>>
>> I know I can permute entire columns this way
>>
>> > M1[,sample(6,6)]
>> 5 x 6 sparse Matrix of class "dgTMatrix"
>>
>> [1,] 5.003        .           .           .       1.656    2.983
>> [2,]     .             .           .           .       2.990       .
>> [3,] 1.115    0.592      .           .       5.349       .
>> [4,]     .             .           .          .       2.804     1.836
>> [5,]     .         6.961   1.077     .          .            .
>>
>> But I would like the new sparse matrix to look like this...where only
> the
>> nonzero elements are permuted.
>>
>> [1,] 1.656      .     5.003    2.983    .        .
>> [2,]    .            .     2.990        .         .        .
>> [3,]    .    5.349    1.115    0.592    .        .
>> [4,] 2.804      .     1.836        .         .        .
>> [5,]    .     1.077       .             .         .     6.961
>>

A peculiar request but you can do that by permuting the 'x' slot in

> set.seed(1)
> (M1 <- spMatrix(nrow=5,ncol=6,i=sample(5,15,replace=TRUE),j=sample(6, 15,replace=TRUE),x=round(rnorm(15,2),3)))
5 x 6 sparse Matrix of class "dgTMatrix"

[1,] .     .     2.738  .     3.595 .
[2,] .     .     .      .     .     .
[3,] 3.879 .     4.289 -0.215 1.374 .
[4,] .     4.966 1.180  1.379 .     2.487
[5,] 3.512 .     .      .     2.330 .
> (nnz <- nnzero(M1))
[1] 15
> M2 <- M1
> M2 at x <- M2 at x[sample(nnz, nnz)]
> M2
5 x 6 sparse Matrix of class "dgTMatrix"

[1,] .     .     2.487 .      3.595 .
[2,] .     .     .     .      .     .
[3,] 3.709 .     2.875 3.512 -0.215 .
[4,] .     3.764 1.164 2.576  .     3.125
[5,] 2.184 .     .     .      2.738 .

>
> I don't have experience with sparse matrices, but I was able to get this
> to work by converting the sparse matrix to a "base" matrix and back again.
>
>
> library(Matrix)
>
> nonzero.cols <- !apply(M1==0, 2, all)
> M2 <- as.matrix(M1)
> reord <- sample(seq(dim(M1)[2])[nonzero.cols])
> M2[, nonzero.cols] <- as.matrix(M1[, reord])
> Matrix(M2, sparse=TRUE)

This solution has the disadvantage of converting the sparse matrix to
a dense matrix, which may end up producing a much larger object.

```