## Generate list of all possible combinations of elements of vector

You're looking for `expand.grid`

.

`expand.grid(0:1, 0:1, 0:1)`

Or, for the long case:

`n <- 14`

l <- rep(list(0:1), n)

expand.grid(l)

## Generate all unique combinations from a vector with repeating elements

Use `combn()`

with `lapply()`

should do the trick.

`x <- c('red', 'blue', 'green', 'red', 'green', 'red')`

lapply(1:3, function(y) combn(x, y))

# [[1]]

# [,1] [,2] [,3] [,4] [,5] [,6]

# [1,] "red" "blue" "green" "red" "green" "red"

# [[2]]

# [,1] [,2] [,3] [,4] [,5] [,6] ...

# [1,] "red" "red" "red" "red" "red" "blue" ...

# [2,] "blue" "green" "red" "green" "red" "green" ...

# [[3]]

# [,1] [,2] [,3] [,4] [,5] [,6] ...

# [1,] "red" "red" "red" "red" "red" "red" ...

# [2,] "blue" "blue" "blue" "blue" "green" "green" ...

# [3,] "green" "red" "green" "red" "red" "green" ...

All unique combinations

`lapply(cc, function(y)`

y[,!duplicated(apply(y, 2, paste, collapse="."))]

)

[[1]]

[1] "red" "blue" "green"

[[2]]

[,1] [,2] [,3] [,4] [,5] [,6] [,7]

[1,] "red" "red" "red" "blue" "blue" "green" "green"

[2,] "blue" "green" "red" "green" "red" "red" "green"

[[3]]

[,1] [,2] [,3] [,4] [,5] [,6] [,7] ...

[1,] "red" "red" "red" "red" "red" "red" "blue" ...

[2,] "blue" "blue" "green" "green" "red" "red" "green" ...

[3,] "green" "red" "red" "green" "green" "red" "red" ...

Although strictly speaking those aren't all unique combinations, as some of them are permutations of each other.

Properly unique combinations

`lapply(cc, function(y)`

y[,!duplicated(apply(y, 2, function(z) paste(sort(z), collapse=".")))]

)

# [[1]]

# [1] "red" "blue" "green"

# [[2]]

# [,1] [,2] [,3] [,4] [,5]

# [1,] "red" "red" "red" "blue" "green"

# [2,] "blue" "green" "red" "green" "green"

# [[3]]

# [,1] [,2] [,3] [,4] [,5] [,6]

# [1,] "red" "red" "red" "red" "red" "blue"

# [2,] "blue" "blue" "green" "green" "red" "green"

# [3,] "green" "red" "red" "green" "red" "green"

## all possible combinations of a list of vectors

you could try

`lapply(2:3, function(k) { lapply(1:length(DF),function(x){ combn(DF[[x]],k, `

simplify = FALSE)})})

## Generate all combinations of vector with consecutive occurrences is considered as single occurrence

Here's an approach using the very fast `arrangements`

package for permutations. We calculate the permutations of integers corresponding to the unique elements of the input and then do some clever indexing to output the corresponding swaps. This is extremely fast on small examples and does pretty well on larger example - on my computer it took a little less than 7 seconds to generate the `10! = 3628800`

swaps on input of size 30 with 10 unique elements. The results are conveniently returned in a `list`

.

`library(arrangements)`

all_swaps = function(x) {

ux = unique(x)

xi = as.integer(factor(x))

perm = permutations(seq_along(ux))

apply(perm, MARGIN = 1, FUN = \(p) ux[p][xi], simplify = FALSE)

}

Test cases from the question:

`# n = 2`

all_swaps(c("a","a","a","b","b","b","a","a","b","b"))

# [[1]]

# [1] "a" "a" "a" "b" "b" "b" "a" "a" "b" "b"

#

# [[2]]

# [1] "b" "b" "b" "a" "a" "a" "b" "b" "a" "a"

## n = 3

all_swaps(c("a","a","a","b","b","b","c","c","c"))

# [[1]]

# [1] "a" "a" "a" "b" "b" "b" "c" "c" "c"

#

# [[2]]

# [1] "a" "a" "a" "c" "c" "c" "b" "b" "b"

#

# [[3]]

# [1] "b" "b" "b" "a" "a" "a" "c" "c" "c"

#

# [[4]]

# [1] "b" "b" "b" "c" "c" "c" "a" "a" "a"

#

# [[5]]

# [1] "c" "c" "c" "a" "a" "a" "b" "b" "b"

#

# [[6]]

# [1] "c" "c" "c" "b" "b" "b" "a" "a" "a"

A shorter demo with 3 unique elements in a "complex" case where the elements are not all consecutive:

`all_swaps(c("a", "b", "b", "c", "b"))`

# [[1]]

# [1] "a" "b" "b" "c" "b"

#

# [[2]]

# [1] "a" "c" "c" "b" "c"

#

# [[3]]

# [1] "b" "a" "a" "c" "a"

#

# [[4]]

# [1] "b" "c" "c" "a" "c"

#

# [[5]]

# [1] "c" "a" "a" "b" "a"

#

# [[6]]

# [1] "c" "b" "b" "a" "b"

A larger case:

`# n = 10`

set.seed(47)

start_t = Sys.time()

n10 = all_swaps(sample(letters[1:10], size = 30, replace = TRUE))

end_t = Sys.time()

end_t - start_t

# Time difference of 6.711215 secs

length(n10)

# [1] 3628800

#### Benchmarking

Benchmarking my answer with Maël's and ThomasIsCoding's, my method relying on the `arrangements`

package is quick and memory efficient. ThomasIsCoding's answer can be improved by changing from `pracma::perms`

to `arrangements::permutations`

--the memory usage is especially improved--but my version still performs better. Maël's uses a lot of time and memory. I'll lead with results, code to reproduce is below.

`## 5 Unique Elements`

arrange(b5, desc(`itr/sec`))

# # A tibble: 4 × 13

# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time

# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>

# 1 GregorThomas 2.31ms 12.6ms 77.5 5.77KB 0 40 0 516ms

# 2 ThomasIsCodingArr(in5) 9.3ms 20.5ms 47.4 19.55KB 0 24 0 506ms

# 3 ThomasIsCoding(in5) 12.57ms 22.7ms 41.2 45.41KB 0 22 0 534ms

# 4 Mael 963.64ms 963.6ms 1.04 1.24MB 0 1 0 964ms

# # … with 4 more variables: result <list>, memory <list>, time <list>, gc <list>

## 9 Unique Elements - memory allocation is important

arrange(b9, desc(`itr/sec`))

# # A tibble: 2 × 13

# expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time result

# <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm> <list>

# 1 GregorThomas 1.8s 1.8s 0.556 27.7MB 0 1 0 1.8s <NULL>

# 2 ThomasIsCoding(in9) 2.5s 2.5s 0.400 230.8MB 0.400 1 1 2.5s <NULL>

# # … with 3 more variables: memory <list>, time <list>, gc <list>

Benchmarking code:

`## Functions`

library(arrangements)

library(pracma)

ThomasIsCoding <- function(x) {

idx <- match(x, unique(x))

m <- asplit(matrix(unique(x)[perms(1:max(idx))], ncol = max(idx)), 1)

Map(`[`, m, list(idx))

}

ThomasIsCodingArr <- function(x) {

idx <- match(x, unique(x))

m <- asplit(matrix(unique(x)[permutations(1:max(idx))], ncol = max(idx)), 1)

Map(`[`, m, list(idx))

}

Mael <- function(vec){

uni <- unique(vec)

size <- length(uni)

pVec <- paste(uni, collapse = "")

grid <- expand.grid(rep(list(uni), size))

expanded <- grid[apply(grid, 1, function(x) length(unique(x))) == size,]

p <- unname(apply(expanded, 1, paste0, collapse = ""))

lapply(p, function(x) chartr(pVec, x, vec))

}

all_swaps = function(x) {

ux = unique(x)

xi = as.integer(factor(x))

perm = permutations(seq_along(ux))

apply(perm, MARGIN = 1, FUN = \(p) ux[p][xi], simplify = FALSE)

}

set.seed(47)

in5 = c(sample(letters[1:5], 5), sample(letters[1:5], 5, replace = TRUE))

b5 = bench::mark(

GregorThomas = all_swaps(in5),

Mael = Mael(in5),

ThomasIsCoding(in5),

ThomasIsCodingArr(in5),

check = FALSE

)

## All possible combinations of elements of three vectors in Python

You could use numpy.meshgrid() like so:

`np.array(np.meshgrid([4, 6], [2, 4], [1, 5])).T.reshape(-1,3)`

Which results in:

` array([[4, 2, 1],`

[4, 4, 1],

[6, 2, 1],

[6, 4, 1],

[4, 2, 5],

[4, 4, 5],

[6, 2, 5],

[6, 4, 5]])

## How to get all possible combinations of array elements without duplicate

Judging from your desired result, you want all the combinations with 2 choices of `'A'`

, `'B'`

, `'C'`

, and `''`

(nothing). You can do it with `nchoosek`

as follows

`result = nchoosek(' ABC', 2) % note space for empty`

Output

`result =`

6×2 char array

' A'

' B'

' C'

'AB'

'AC'

'BC'

Then removing the spaces and converting the combinations to a cell array:

`result = strrep(cellstr(result), ' ', '')`

As Wolfie pointed out, this only works for single character input, for multi character inputs we can use string arrays instead of char arrays:

`result = nchoosek(["","A1","B2","C3"], 2);`

result = result(:,1) + result(:,2) % string cat

% result = cellstr(result); % optional if want cell output

`result = `

6×1 string array

"A1"

"B2"

"C3"

"A1B2"

"A1C3"

"B2C3"

## R find all possible unique combinations

There are a few packages specifically built for this. The basic premise is that we need combinations with repetition of length `m`

where `m`

could be larger than the input vector. We start with the classic `gtools`

:

`library(gtools)`

combinations(2, 3, letters[1:2], repeats.allowed = TRUE)

[,1] [,2] [,3]

[1,] "a" "a" "a"

[2,] "a" "a" "b"

[3,] "a" "b" "b"

[4,] "b" "b" "b"

And then there is `arrangements`

which is a replacement for `iterpc`

(the package linked by @Gregor in the comments above):

`library(arrangements)`

arrangements::combinations(2, 3, letters[1:2], replace = TRUE)

[,1] [,2] [,3]

[1,] "a" "a" "a"

[2,] "a" "a" "b"

[3,] "a" "b" "b"

[4,] "b" "b" "b"

And finally there is `RcppAlgos`

, which I authored:

`library(RcppAlgos)`

comboGeneral(letters[1:2], 3, TRUE)

[,1] [,2] [,3]

[1,] "a" "a" "a"

[2,] "a" "a" "b"

[3,] "a" "b" "b"

[4,] "b" "b" "b"

`combn`

is an awesome function that ships as one of the base packages with `R`

, however one of its shortcomings is that it doesn't allow repetition (which is what is required here). I wrote a pretty comprehensive overview for problems exactly like this one that can be found here: A Walk Through a Slice of Combinatorics in R.

## generate all combinations of a variable number of vectors in MATLAB

You can unpack a cell with `mycell{:}`

, if passed as an argument; each element of the cell will be interpreted as a new argument:

`v1 = [1,2,3];`

v2 = [2,3,4];

v3 = [3,4,5];

% We put everything in a cell

v = {v1,v2,v3};

% We unpack our cell into combvec

combvec(v{:})

Of course this example is pretty useless, but in a real case situation you can simply store your vectors directly in a cell `v{ii} = ...`

### Related Topics

How to Remove Rows With Any Zero Value

Remove Specific Characters from Column Names in R

How to Get Rowsums for Selected Columns in R

Adding a New Column Based Upon Values in Another Column Using Dplyr

Calculate Max Value Across Multiple Columns by Multiple Groups

How to Add Row and Column to a Dataframe of Different Length

How to Sort a Data Frame by Alphabetic Order of a Character Variable in R

Creating a New Column Based on Unique Id With Values in R

How to Remove Na from a Factor Variable (And from a Ggplot Chart)

R - Test If a String Vector Contains Any Element of Another List

Rstudio Suddenly Stopped Showing Plots in the Plot Pane

Difference Between Require() and Library()

Formatting Decimal Places in R

Select/Assign to Data.Table When Variable Names Are Stored in a Character Vector

How to Get Summary Statistics by Group

How to Trim Leading and Trailing White Space

Merge 2 Data Frames in a Loop for Each Column in One of Them