Reputation: 5696
I would like to generate different possible permutations with the same frequency as in the input vector. For example, I would like to generate the permutations using the vector x
in the below example.
library(gtools)
x <- c('A','A','B')
permutations(2, 3, x, repeats.allowed = T)
It gives the below output.
# [,1] [,2] [,3]
# [1,] "A" "A" "A"
# [2,] "A" "A" "B"
# [3,] "A" "B" "A"
# [4,] "A" "B" "B"
# [5,] "B" "A" "A"
# [6,] "B" "A" "B"
# [7,] "B" "B" "A"
# [8,] "B" "B" "B"
But, I want only permutations having A
, B
with frequencies 2, 1 respectively. The expected output is:
# [,1] [,2] [,3]
# [1,] "A" "A" "B"
# [2,] "A" "B" "A"
# [3,] "B" "A" "A"
Is there any function available in R?
Note: I do not want to do post-processing of the output to get the expected output as my original input contains 300 elements. It is not recommended to generate factorial(300)
number of permutations.
Update: The suggested link provides a nice faster solution but fails when the input vector is doubled (eg: length=20
) with the error message:
Error in matrix(NA, nrow = N, ncol = prod(sapply(foo, ncol))) :
invalid 'ncol' value (too large or NA)
Upvotes: 2
Views: 479
Reputation: 13691
Your problem can be reformulated as finding all possible permutations of the frequency vector. Take a look at combinat::permn
:
x <- c( 'A', 'A', 'B' )
unique(combinat::permn( x ))
# [[1]]
# [1] "A" "A" "B"
# [[2]]
# [1] "A" "B" "A"
# [[3]]
# [1] "B" "A" "A"
unique
is necessary to remove duplicate entries, which is automatically done by gtools::permutations
you've been using (through the default set=TRUE
argument).
If you need the result in matrix format, as in your original question, pass the output as arguments to rbind
using do.call
:
do.call( rbind, unique(combinat::permn( x )) )
# [,1] [,2] [,3]
# [1,] "A" "A" "B"
# [2,] "A" "B" "A"
# [3,] "B" "A" "A"
Upvotes: 2