RainieJin
RainieJin

Reputation: 51

How to generate all permutations of lists of string?

I have character data like this

[[1]]
[1] "F" "S"

[[2]]
[1] "Y" "Q" "Q"

[[3]]
[1] "C" "T"

[[4]]
[1] "G" "M"

[[5]]
[1] "A" "M"

And I want to generate all permutations for each individual list (not mixed between lists) and combine them together into one big list.

For example, for the first and second lists, which are "F" "S" and "Y" "Q" "Q", I want to get the permutation lists as c("FS", "SF"), and c("YQQ", "QYQ", "QQY"), and then combine them into one.

Upvotes: 1

Views: 390

Answers (3)

Ashish Baid
Ashish Baid

Reputation: 533

library(combinat)

final <- unlist(lapply(X , function(test_X) lapply(permn(test_X), function(x) paste(x,collapse='')) ))

Upvotes: 1

Damian
Damian

Reputation: 1433

It looks like your desired output is not exactly the same as this related post (Generating all distinct permutations of a list in R). But we can build on the answer there.

library(combinat)

# example data, based on your description
X <- list(c("F","S"), c("Y", "Q", "Q"))

result <- lapply(X, function(x1) {
    unique(sapply(permn(x1), function(x2) paste(x2, collapse = "")))
})

print(result)

Output

 [[1]]
 [1] "FS" "SF"

 [[2]]
 [1] "YQQ" "QYQ" "QQY"

The first (outer) lapply iterates over each element of the list, which contains the individual letters (in a vector). With each iteration the permn takes the individual letters (eg "F" and "S"), and returns a list object with all possible permutations (e.g "F" "S" and "S" F"). To format the output as you described, the inner sapply takes each those permutations and collapses them into a single character value, filtered for unique values.

Upvotes: 1

Ian Campbell
Ian Campbell

Reputation: 24790

Here's an approach with combinat::permn:

library(combinat)
lapply(data,function(x)unique(sapply(combinat::permn(x),paste,collapse = "")))
#[[1]]
#[1] "FS" "SF"
#
#[[2]]
#[1] "YQQ" "QYQ" "QQY"
#
#[[3]]
#[1] "CT" "TC"
#
#[[4]]
#[1] "GM" "MG"
#
#[[5]]
#[1] "AM" "MA"

Or together with unlist:

unlist(lapply(data,function(x)unique(sapply(combinat::permn(x),paste,collapse = ""))))
# [1] "FS"  "SF"  "YQQ" "QYQ" "QQY" "CT"  "TC"  "GM"  "MG"  "AM"  "MA" 

Data:

data <- list(c("F", "S"), c("Y", "Q", "Q"), c("C", "T"), c("G", "M"), 
    c("A", "M"))

Upvotes: 1

Related Questions