2
c(2:5,
1:1,
3:5,
1:2,
4:5,
1:3,
5:5,
1:4)
> 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4.

As one can see there is a pattern here. Starting at n=5 n-3:n, counting down and then followed by 1:n-4 and so on. My question is there any way to automate this using seq() and rep() in R?

user2007598
  • 163
  • 8

4 Answers4

4

I guess you could view this as a loop of some variable d from 3 to 0 where for each value d you add the following two vectors:

(n-d):n
1:(n-d-1)

Armed with this analysis, we can pretty easily perform this as a one-liner:

n <- 5
as.vector(sapply(3:0, function(d) c((n-d):n, 1:(n-d-1))))
# [1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4

Another way that would be a bit more efficient but in my opinion less understandable could use outer and modulo:

as.vector(outer(0:(n-1), 3:0, function(x, y) (x-y-1) %% n + 1))
# [1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4
josliber
  • 43,891
  • 12
  • 98
  • 133
3

You can also use:

c(sapply(1:5, function(u) (1:5)[-u]))
#[1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4
Colonel Beauvel
  • 30,423
  • 11
  • 47
  • 87
  • Ah, great pattern matching on the output sequence -- this is definitely the simplest approach yet! Because the OP had used four groups of five I hadn't thought to look at the sequence as five groups of four. – josliber Aug 05 '15 at 12:44
  • fortunately we are reasonning in a commutative division ring :) – Colonel Beauvel Aug 05 '15 at 12:50
2

Interleaving lists. You can use @Arun's approach to interleaving two lists:

a = lapply(2:5, function(x) x:5)
b = lapply(1:4, function(x) 1:x)

idx <- order(c(seq_along(a), seq_along(b)))
unlist(c(a,b)[idx])
# [1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4

Matrix tricks. Alternately, try some matrix-index trickery:

n = 5
m = matrix(,n,n-1)
v = c( col(m) + row(m) ) %% n

v + n*!v
# [1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4
Community
  • 1
  • 1
Frank
  • 66,179
  • 8
  • 96
  • 180
2

To expand on josilber's answer (I thought of it as a repeating circular shift):

n=5
d=4
as.vector(sapply(seq(d),function(x, y) c(tail(y, -x), head(y, x)), y=seq(n)))
[1] 2 3 4 5 1 3 4 5 1 2 4 5 1 2 3 5 1 2 3 4
N8TRO
  • 3,348
  • 3
  • 22
  • 40