1

Extending this former question, how can I shuffle (randomize) the following vector

a1 = c(1, 1, 2, 2, 2, 2, 3, 3, 4, 5, 5, 5) 

in order to get something like this:

a2 = c(5, 5, 3, 3, 3, 3, 1, 1, 2, 4, 4, 4)

or even better like this:

a3 = c(4, 4, 4, 2, 3, 3, 3, 3, 1, 1, 5, 5)? 

such that each element could randomly change to another but with keeping the number of each element constant?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Rotail
  • 1,025
  • 4
  • 19
  • 40

3 Answers3

4

You can try something like this: create a factor from a1 with randomly shuffled levels and then convert it to integers:

as.integer(factor(a1, levels = sample(unique(a1), length(unique(a1)))))
# [1] 5 5 4 4 4 4 3 3 2 1 1 1
Psidom
  • 209,562
  • 33
  • 339
  • 356
3

Seems like a perfect application for rle and its inverse rep:

rand_inverse_rle <- function(x) { x=sort(x)
   ord=sample (length(rle(x)$values) )  
   unlist( mapply( rep, rle(x)$values[ord], rle(x)$lengths[ord]))}
rand_inverse_rle(a1)
#----------
 [1] 3 3 4 5 5 5 2 2 2 2 1 1

This was my reading of a function needed to satisfy the natural language requirements:

>  a1 = sample( c(1, 1, 2, 2, 2, 2, 3, 3, 4, 5, 5, 5) )
> a1
 [1] 5 2 5 2 5 1 3 4 2 2 3 1
> rand_inverse_rle(a1)
 [1] 5 5 5 4 2 2 2 2 3 3 1 1
> rand_inverse_rle(a1)
 [1] 1 1 3 3 5 5 5 2 2 2 2 4
> rand_inverse_rle(a1)
 [1] 1 1 3 3 4 5 5 5 2 2 2 2
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • 1
    i don't know whether sorting is needed. It _was_ needed for my reading of the English language description, even if the example had already been sorted.. addendum added. – IRTFM Oct 22 '16 at 04:14
3

The data:

a1 <- c(1, 1, 2, 2, 2, 2, 3, 3, 4, 5, 5, 5)

First steps:

# extract values and their frequencies
val <- unique(a1)

tab <- table(a1)
freq <- tab[as.character(val)]

Keep original order of frequencies but sample values

rep(sample(val), freq)
# [1] 4 4 1 1 1 1 3 3 5 2 2 2

Keep original frequencies but sample order of values

rep(sa <- sample(val), freq[as.character(sa)])
# [1] 4 2 2 2 2 3 3 1 1 5 5 5
Sven Hohenstein
  • 80,497
  • 17
  • 145
  • 168