Generating All Distinct Permutations of a List in R

Generating all distinct permutations of a list in R

combinat::permn will do that work:

> library(combinat)
> permn(letters[1:3])
[[1]]
[1] "a" "b" "c"

[[2]]
[1] "a" "c" "b"

[[3]]
[1] "c" "a" "b"

[[4]]
[1] "c" "b" "a"

[[5]]
[1] "b" "c" "a"

[[6]]
[1] "b" "a" "c"

Note that calculation is huge if the element is large.

Print all permutations of a vector of characters in R

This can be easily done using the gtools package.

prm <- gtools::permutations(n=10, r=3, v=LETTERS[1:10])

Then you can apply paste0 across the rows to get a vector.

apply(prm, 1, function(x)paste0(x, collapse=''))

R- Find Unique Permutations of Values

It should not be a dealbreaker that expand.grid includes all permutations. Just add a subset after:

combinations <- function(size, choose) {

d <- do.call("expand.grid", rep(list(0:1), size))
d[rowSums(d) == choose,]

}

combinations(size=10, choose=3)
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 8 1 1 1 0 0 0 0 0 0 0
# 12 1 1 0 1 0 0 0 0 0 0
# 14 1 0 1 1 0 0 0 0 0 0
# 15 0 1 1 1 0 0 0 0 0 0
# 20 1 1 0 0 1 0 0 0 0 0
# 22 1 0 1 0 1 0 0 0 0 0
...

R: generate all unique permutations from a vector

Use it like this:

library(RcppAlgos)

tab <- table(ex)
permuteGeneral(v = names(tab), freq = tab)
## [,1] [,2] [,3]
## [1,] "sp1" "sp2" "sp2"
## [2,] "sp2" "sp1" "sp2"
## [3,] "sp2" "sp2" "sp1"

How to extract permutations of all unique factor levels within a list

You can do it by using the group_split from dplyr.

Df %>% group_split(Condition, Level, Response)

How to generate permutations or combinations of object in R?

EDIT: I have updated the answer to use a more efficient package arrangements

Getting start of using arrangement

arrangements contains some efficient generators and iterators for permutations and combinations. It has been demonstrated that arrangements outperforms most of the existing packages of similar kind. Some benchmarks could be found here.

Here are the answers to the above questions

# 1) combinations: without replacement: distinct items

combinations(5, 2)

[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 1 5
[5,] 2 3
[6,] 2 4
[7,] 2 5
[8,] 3 4
[9,] 3 5
[10,] 4 5


# 2) combinations: with replacement: distinct items

combinations(5, 2, replace=TRUE)

[,1] [,2]
[1,] 1 1
[2,] 1 2
[3,] 1 3
[4,] 1 4
[5,] 1 5
[6,] 2 2
[7,] 2 3
[8,] 2 4
[9,] 2 5
[10,] 3 3
[11,] 3 4
[12,] 3 5
[13,] 4 4
[14,] 4 5
[15,] 5 5



# 3) combinations: without replacement: non distinct items

combinations(x = c("a", "b", "c"), freq = c(2, 1, 1), k = 2)

[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "c"



# 4) combinations: with replacement: non distinct items

combinations(x = c("a", "b", "c"), k = 2, replace = TRUE) # as `freq` does not matter

[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "b"
[5,] "b" "c"
[6,] "c" "c"

# 5) permutations: without replacement: distinct items

permutations(5, 2)

[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 1 5
[5,] 2 1
[6,] 2 3
[7,] 2 4
[8,] 2 5
[9,] 3 1
[10,] 3 2
[11,] 3 4
[12,] 3 5
[13,] 4 1
[14,] 4 2
[15,] 4 3
[16,] 4 5
[17,] 5 1
[18,] 5 2
[19,] 5 3
[20,] 5 4



# 6) permutations: with replacement: distinct items

permutations(5, 2, replace = TRUE)

[,1] [,2]
[1,] 1 1
[2,] 1 2
[3,] 1 3
[4,] 1 4
[5,] 1 5
[6,] 2 1
[7,] 2 2
[8,] 2 3
[9,] 2 4
[10,] 2 5
[11,] 3 1
[12,] 3 2
[13,] 3 3
[14,] 3 4
[15,] 3 5
[16,] 4 1
[17,] 4 2
[18,] 4 3
[19,] 4 4
[20,] 4 5
[21,] 5 1
[22,] 5 2
[23,] 5 3
[24,] 5 4
[25,] 5 5


# 7) permutations: without replacement: non distinct items

permutations(x = c("a", "b", "c"), freq = c(2, 1, 1), k = 2)

[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "a"
[5,] "b" "c"
[6,] "c" "a"
[7,] "c" "b"



# 8) permutations: with replacement: non distinct items

permutations(x = c("a", "b", "c"), k = 2, replace = TRUE) # as `freq` doesn't matter

[,1] [,2]
[1,] "a" "a"
[2,] "a" "b"
[3,] "a" "c"
[4,] "b" "a"
[5,] "b" "b"
[6,] "b" "c"
[7,] "c" "a"
[8,] "c" "b"
[9,] "c" "c"

Compare to other packages

There are few advantages of using arrangements over the existing packages.

  1. Integral framework: you don't have to use different packages for different methods.

  2. It is very efficient. See https://randy3k.github.io/arrangements/articles/benchmark.html for some benchmarks.

  3. It is memory efficient, it is able to generate all 13! permutation of 1 to 13, existing packages will fail to do so because of the limitation of matrix size. The getnext() method of the iterators allow users to get the arrangements one by one.

  4. The generated arrangements are in dictionary order which may be desired for some users.

compute all permutation with repetition of list R

I think this is what the OP is looking for:

out <- list(c("(1,5)","(3)","(4)","(6)"), c("(3,6)","(1)","(4)","(5)"), 
c("(3,4)","(1)","(5)","(6)"),c("(3,5)","(1)","(4)","(6)"),
c("(4,6)","(1)","(3)","(5)"), c("(4,5)","(1)","(3)","(6)"),
c("(5,6)","(1)","(3)","(4)"))

library(RcppAlgos)
myPerms <- lapply(out, function(x) {
unlist(permuteGeneral(x, length(x), FUN = function(y) {
paste0(c("{", y, "}"), collapse = "")
}))
})

We use permuteGeneral from RcppAlgos (I am the author) as we can utilize the FUN argument to pass a custom function that will be applied to each permutation (i.e. paste0(c("{", y, "}"), collapse = "")).

Here is the output of the 5th element:

myPerms[[5]]
[1] "{(4,6)(1)(3)(5)}" "{(4,6)(1)(5)(3)}" "{(4,6)(3)(1)(5)}"
[4] "{(4,6)(3)(5)(1)}" "{(4,6)(5)(1)(3)}" "{(4,6)(5)(3)(1)}"
[7] "{(1)(4,6)(3)(5)}" "{(1)(4,6)(5)(3)}" "{(1)(3)(4,6)(5)}"
[10] "{(1)(3)(5)(4,6)}" "{(1)(5)(4,6)(3)}" "{(1)(5)(3)(4,6)}"
[13] "{(3)(4,6)(1)(5)}" "{(3)(4,6)(5)(1)}" "{(3)(1)(4,6)(5)}"
[16] "{(3)(1)(5)(4,6)}" "{(3)(5)(4,6)(1)}" "{(3)(5)(1)(4,6)}"
[19] "{(5)(4,6)(1)(3)}" "{(5)(4,6)(3)(1)}" "{(5)(1)(4,6)(3)}"
[22] "{(5)(1)(3)(4,6)}" "{(5)(3)(4,6)(1)}" "{(5)(3)(1)(4,6)}"

If you really want permutations with repetition, simply set repetition = TRUE in permuteGeneral. Of course, if you want a more useable output, we can drop the custom FUN altogether.

UPDATE

After learning more about how the OP obtained out above, we can better attack the problem. First we find out that the OP uses listParts from the library partitions. Looking at the source code we have:

listParts
function (x)
{
f <- function(pp) {
out <- split(seq_along(pp), pp)
class(out) <- c(class(out), "equivalence")
out
}
apply(setparts(x), 2, f)
}
<bytecode: 0x10d7b09f8>
<environment: namespace:partitions>

We can alter this to obtain all permutations:

permListParts <- function (x) 
{
f <- function(pp) {
out <- split(seq_along(pp), pp)
myPerms <- perms(length(out))
apply(myPerms, 2, function(x) {
temp <- out[x]
class(temp) <- c(class(temp), "equivalence")
temp
})
}
apply(setparts(x), 2, f)
}

We note that we are going against the intent of listParts... quoting the documentation:

"Note that (12)(3)(4) is the same partition as, for example, (3)(4)(21) as the equivalence relation is the same."

Oh well... here is the output for permutations of length 3:

permListParts(3)
[[1]]
[[1]][[1]]
[1] (1,2,3)


[[2]]
[[2]][[1]]
[1] (1,3)(2)

[[2]][[2]]
[1] (2)(1,3)


[[3]]
[[3]][[1]]
[1] (1,2)(3)

[[3]][[2]]
[1] (3)(1,2)


[[4]]
[[4]][[1]]
[1] (2,3)(1)

[[4]][[2]]
[1] (1)(2,3)


[[5]]
[[5]][[1]]
[1] (1)(2)(3)

[[5]][[2]]
[1] (1)(3)(2)

[[5]][[3]]
[1] (2)(1)(3)

[[5]][[4]]
[1] (2)(3)(1)

[[5]][[5]]
[1] (3)(1)(2)

[[5]][[6]]
[1] (3)(2)(1)


Related Topics



Leave a reply



Submit