Common decision:
Edit: as @MatthewLundberg's comments, the problem I pointed out with "repeating numbers in x" can be easily overcome by working on seq_along(x) , which would mean that the resulting values ​​will be indexes. So it will be like this:
k <- 3 x <- c(2,2,1, 1,3,4, 4,6,5, 3) xs <- seq_along(x) y <- sample(xs) x[unlist(split(y, (match(y, xs)-1) %/% k), use.names = FALSE)] # [1] 2 2 1 3 4 1 4 5 6 3
Old answer:
The bottleneck here is the number of calls to the sample function. And while your numbers are not repeating, I think you can do it with one call to sample as follows:
k <- 3 x <- 1:20 y <- sample(x) unlist(split(y, (match(y,x)-1) %/% k), use.names = FALSE)
Put it all together in a function (I like @ Roland's scramble name):
scramble <- function(x, k=3) { xs <- seq_along(x) ys <- sample(xs) idx <- unlist(split(ys, (match(ys, xs)-1) %/% k), use.names = FALSE) x[idx] } scramble(x, 3) # [1] 2 1 2 3 4 1 5 4 6 3 scramble(x, 3) # [1] 1 2 2 1 4 3 6 5 4 3
To reduce the answer (and get it faster), even more after the comment by @flodel:
scramble <- function(x, k=3L) { xs <- seq_along(x) ys <- sample(xs) x[unlist(split(xs[ys], (ys-1) %/% k), use.names = FALSE)] }