Reputation: 59
I am trying to create a function that will do the following:
input: 1:3
output: 1 2 3 2 3 1 3 1 2
In this way i want to generate all permutations of the input where the elements never overlap for each given index
1 2 3 and 2 3 1 and 3 1 2
I have come as far as:
sapply(1:4,(function(i){paste0(i,i+1,i+2,i+3)}))
but this does not generate the output i am looking for.
Upvotes: 2
Views: 168
Reputation: 39727
Reading your comment in looks like you can use matrix
to generate the wanted numbers like:
n <- 2
matrix(1:n, n+1, n)[1:n,]
# [,1] [,2]
#[1,] 1 2
#[2,] 2 1
n <- 3
matrix(1:n, n+1, n)[1:n,]
# [,1] [,2] [,3]
#[1,] 1 2 3
#[2,] 2 3 1
#[3,] 3 1 2
n <- 4
matrix(1:n, n+1, n)[1:n,]
# [,1] [,2] [,3] [,4]
#[1,] 1 2 3 4
#[2,] 2 3 4 1
#[3,] 3 4 1 2
#[4,] 4 1 2 3
n <- 5
matrix(1:n, n+1, n)[1:n,]
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 2 3 4 5
#[2,] 2 3 4 5 1
#[3,] 3 4 5 1 2
#[4,] 4 5 1 2 3
#[5,] 5 1 2 3 4
My first answer to generate all permutations in base using expand.grid
was:
x <- 1:3
do.call(expand.grid, lapply(x, \(i) x)) ->.
.[apply(., 1, anyDuplicated) == 0,]
# Var1 Var2 Var3
#6 3 2 1
#8 2 3 1
#12 3 1 2
#16 1 3 2
#20 2 1 3
#22 1 2 3
Upvotes: 3
Reputation: 270268
I assume that problem is that we are given n and we want a vector containing 1:n followed by each permutation of 1:n for which the ith element of each such permutation is not i. We generate all permutations and then eliminate those for which the ith position equals i for all i in 1:n, i.e. if P is permutation of 1:n then we only accept it if all(P != 1:n) is TRUE. The calculation below will get large very quickly but for small n it should be ok.
library(RcppAlgos)
n <- 2
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 2 1
n <- 3
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 3 2 3 1 3 1 2
n <- 4
p <- permuteGeneral(n)
c(cbind(1:n, t(p[apply(t(p) != 1:n, 2, all), , drop = FALSE])))
## [1] 1 2 3 4 2 1 4 3 2 3 4 1 2 4 1 3 3 1 4 2 3 4 1 2 3 4 2 1 4 1 2 3 4 3 1 2 4 3 2 1
Upvotes: 3
Reputation: 1202
You can also use the permutations function from gtools package:
permutations(n=3,r = 3,v = 1:3)
The output is
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 3 2
[3,] 2 1 3
[4,] 2 3 1
[5,] 3 1 2
[6,] 3 2 1
Upvotes: 1
Reputation: 8880
if I understand correctly
combinat::permn(x = 1:3)
[[1]]
[1] 1 2 3
[[2]]
[1] 1 3 2
[[3]]
[1] 3 1 2
[[4]]
[1] 3 2 1
[[5]]
[1] 2 3 1
[[6]]
[1] 2 1 3
Upvotes: 2