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? -Diogo
Hi: One way: x[sample(nrow(x)), ] HTH, Dennis On Wed, Feb 9, 2011 at 10:45 PM, Diogo Almeida <dalazal@gmail.com> 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? > -Diogo > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
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.
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. There is also a solution using apply(), which is t(apply(datamatrix, 1, sample)), however, this is not optimized for speed. Let me provide some test results for the suggestion from the previous email. shuffle1 <- function(A) { for (i in 1:nrow(A)) { A[i, ] <- sample(A[i, ]) } A } shuffle2 <- function(A) { B <- t(A) ind <- order(c(col(B)), runif(length(B))) matrix(B[ind], nrow=nrow(A), ncol=ncol(A), byrow=TRUE) } m <- 6 n <- 4 datamatrix <- matrix(1:(m*n), ncol = n) system.time(replicate(10000, shuffle1(datamatrix))) user system elapsed 0.828 0.005 0.834 system.time(replicate(10000, shuffle2(datamatrix))) user system elapsed 0.528 0.001 0.530 m <- 50 n <- 20 datamatrix <- matrix(1:(m*n), ncol = n) system.time(replicate(10000, shuffle1(datamatrix))) user system elapsed 7.787 0.084 7.872 system.time(replicate(10000, shuffle2(datamatrix))) user system elapsed 3.554 0.054 3.608 Petr Savicky.