[R] Permuting rows of a matrix

Petr Savicky savicky at praha1.ff.cuni.cz
Thu Feb 10 09:27:27 CET 2011


On Thu, Feb 10, 2011 at 01:45:46AM -0500, Diogo Almeida wrote:
> Hi,
> 
> I need to permute the rows of a matrix, where each row is independently rearranged. A simple solution is this:
> 
> shuffled <- datamatrix <- matrix(1:24, ncol = 4)
> for (i in 1:nrow(datamatrix)) { shuffled[i, ] <- sample(datamatrix[i, ]) }
> 
> > datamatrix
>      [,1] [,2] [,3] [,4]
> [1,]    1    7   13   19
> [2,]    2    8   14   20
> [3,]    3    9   15   21
> [4,]    4   10   16   22
> [5,]    5   11   17   23
> [6,]    6   12   18   24
> > shuffled
>      [,1] [,2] [,3] [,4]
> [1,]    7   19   13    1
> [2,]    2    8   14   20
> [3,]   15    3    9   21
> [4,]   22   10   16    4
> [5,]    5   11   17   23
> [6,]   24    6   12   18
> 
> However, I need to perform quite a lot of these permutations, and I was wondering whether anyone knows of a faster way of doing this. Something that might not involve a "for" loop, for instance?

Hi.

A random permutation of indices in one row may be obtained using order(runif(4)).
Ordering 6 blocks of random numbers produces blocks of indices, which allow
to permute all rows simultaneously. Try the following.

  shuffled <- datamatrix <- matrix(1:24, ncol = 4)
  shuffled <- t(shuffled)
  ind <- order(c(col(shuffled)), runif(length(shuffled)))
  shuffled <- matrix(shuffled[ind], nrow=nrow(datamatrix), ncol=ncol(datamatrix), byrow=TRUE)
  datamatrix

       [,1] [,2] [,3] [,4]
  [1,]    1    7   13   19
  [2,]    2    8   14   20
  [3,]    3    9   15   21
  [4,]    4   10   16   22
  [5,]    5   11   17   23
  [6,]    6   12   18   24

  shuffled

       [,1] [,2] [,3] [,4]
  [1,]   19   13    1    7
  [2,]    8   14    2   20
  [3,]   21   15    3    9
  [4,]   22   16    4   10
  [5,]   17    5   11   23
  [6,]   12   18   24    6

In my tests, the above was slightly faster than the original code,
but not much. The reason may be that the body of the loop already
performs a computation which requires time significantly larger
than the overhead of the loop. In such a case, avoiding the loop
need not help much.

Petr Savicky.



More information about the R-help mailing list