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.
Integral framework: you don't have to use different packages for different methods.
It is very efficient. See https://randy3k.github.io/arrangements/articles/benchmark.html for some benchmarks.
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.The generated arrangements are in dictionary order which may be desired for some users.
Permutations of list elements in R
You will need to use one of the packages that are able to generate permutations of length n chosen m at a time (See this How to generate permutations or combinations of object in R? for more information). You can then loop over the rows and subset the orginal list:
library(gtools)
apply(permutations(length(my_list), 2), 1, function(x) {
my_list[x]
})
[[1]]
[[1]]$A
[1] "A"
[[1]]$B
[1] "B" "B"
[[2]]
[[2]]$A
[1] "A"
[[2]]$C
[1] "C" "C" "C"
[[3]]
[[3]]$B
[1] "B" "B"
[[3]]$A
[1] "A"
[[4]]
[[4]]$B
[1] "B" "B"
[[4]]$C
[1] "C" "C" "C"
[[5]]
[[5]]$C
[1] "C" "C" "C"
[[5]]$A
[1] "A"
[[6]]
[[6]]$C
[1] "C" "C" "C"
[[6]]$B
[1] "B" "B"
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.
How to get a set of all Combination in R with given conditions?
Thanks @ekoam
lynx <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,6,7,8,9)
comb <- combinations(freq = table(lynx), k = 5, x = unique(lynx))
comb
library: arrangements
Unique Sets Permutations R
conbn
would give you what you need:
#combn gives you the combinations, t is only used to transpose the matrix
t(combn(x, 2))
# [,1] [,2]
#[1,] "A" "B"
#[2,] "A" "C"
#[3,] "A" "D"
#[4,] "B" "C"
#[5,] "B" "D"
#[6,] "C" "D"
R: how to obtain unique pairwise combinations of 2 vectors
We can use combn
f1 <- function(x) setNames(as.data.frame(t(combn(x, 2))), c("x", "y"))
f1(1:3)
# x y
#1 1 2
#2 1 3
#3 2 3
f1(1:4)
# x y
#1 1 2
#2 1 3
#3 1 4
#4 2 3
#5 2 4
#6 3 4
r - combinations from elements in vector
You seem to want permutations, not combinations. Try the function permn()
from the package combinat
:
# Your first example:
combinat::permn(c(1, 2, 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
# Your second example
res <- combinat::permn(c(1,2,3,4,5,6,7,8,9,10))
It does take a while, though. And of course the object itself is going to be large:
system.time(res <- combinat::permn(c(1,2,3,4,5,6,7,8,9,10)))
#> user system elapsed
#> 14.661 0.448 15.346
pryr::object_size(res)
#> 639 MB
Related Topics
Add Legend to Geom_Line() Graph in R
How to Filter Multiple Columns With Same Condition in R
Splitting a Large Data Frame into Smaller Segments
Rstudio Does Not Display Any Output in Console After Entering Code
Change R Default Library Path Using .Libpaths in Rprofile.Site Fails to Work
How Does the 'Prop.Table()' Function Work in R
Saving Output of Confusionmatrix as a .Csv Table
Changing from Upper to Lower Case in Several Data Frames
How to Fix Spaces in Column Names of a Data.Frame (Remove Spaces, Inject Dots)
Extract Rows for the First Occurrence of a Variable in a Data Frame
Sum Across Multiple Columns With Dplyr
Subset/Filter Rows in a Data Frame Based on a Condition in a Column
Storing Ggplot Objects in a List from Within Loop in R