Search code examples
rcombinationsmultinomial

finding set of multinomial combinations


Let's say I have a vector of integers 1:6

w=1:6

I am attempting to obtain a matrix of 90 rows and 6 columns that contains the multinomial combinations from these 6 integers taken as 3 groups of size 2.

6!/(2!*2!*2!)=90

So, columns 1 and 2 of the matrix would represent group 1, columns 3 and 4 would represent group 2 and columns 5 and 6 would represent group 3. Something like:

1 2 3 4 5 6

1 2 3 5 4 6

1 2 3 6 4 5

1 2 4 5 3 6

1 2 4 6 3 5

...

Ultimately, I would want to expand this to other multinomial combinations of limited size (because the numbers get large rather quickly) but I am having trouble getting things to work. I've found several functions that do binomial combinations (only 2 groups) but I could not locate any functions that do this when the number of groups is greater than 2.

I've tried two approaches to this:

  1. Building up the matrix from nothing using for loops and attempting things with the reshape package (thinking that might be something there for this with melt() )

  2. working backwards from the permutation matrix (720 rows) by attempting to retain unique rows within groups and or removing duplicated rows within groups

Neither worked for me.

The permutation matrix can be obtained with

library(gtools)
dat=permutations(6, 6, set=TRUE, repeats.allowed=FALSE)

I think working backwards from the full permutation matrix is a bit excessive but I'm tring anything at this point.

Is there a package with a prebuilt function for this? Anyone have any ideas how I shoud proceed?


Solution

  • Here is how you can implement your "working backwards" approach:

    gps <- list(1:2, 3:4, 5:6)
    
    get.col    <- function(x, j) x[, j]
    is.ordered <- function(x) !colSums(diff(t(x)) < 0)
    is.valid   <- Reduce(`&`, Map(is.ordered, Map(get.col, list(dat),  gps)))
    
    dat <- dat[is.valid, ]
    
    nrow(dat)
    # [1] 90