Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modification of expand.grid function in R

Tags:

r

I need to create a matrix of all possible combinations.

L<-12 
vec <- c(0:21)
lst <- lapply(numeric(L), function(x) vec)
Mat1<-as.matrix(expand.grid(lst))

Result would be very big matrix and my computer cannot calculate it. Actually, I need only combinations where value in the first column is greater then value in the second one, in the second column is greater then in the third one and so on. Can I modify expand.grid function somehow to drop unnecessary combinations?

like image 471
Кирилл Смирнов Avatar asked Jan 25 '23 07:01

Кирилл Смирнов


2 Answers

As @AllanCameron identified, what you're after is equivalent to taking all combinations of vec of size 12 -- you can also use the built-in function combn for that:

do.call(rbind, combn(vec, L, simplify = FALSE))

It may be faster to use data.table to manipulate the output of combn into the desired format:

library(data.table)
setDT(transpose(combn(vec, L, simplify=FALSE))
like image 89
MichaelChirico Avatar answered Jan 30 '23 06:01

MichaelChirico


You can do this quite easily using combinations from the gtools package:

result <- gtools::combinations(length(vec), L, vec)[, L:1]

The function itself gives the columns in increasing order, so the subset is there just to get the order right.

It is a large matrix, so it takes some time, but only around 5 seconds on my slow work PC:

microbenchmark::microbenchmark(combinations(22, 12, 21:0)[,12:1], times = 5)
Unit: seconds
                              expr      min       lq     mean   median       uq      max neval
combinations(22, 12, 21:0)[, 12:1] 4.965595 5.211964 5.261557 5.249413 5.341981 5.538831     5

We can see that the first 5 rows give the correct format:

result[1:5,]
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#> [1,]   11   10    9    8    7    6    5    4    3     2     1     0
#> [2,]   12   10    9    8    7    6    5    4    3     2     1     0
#> [3,]   13   10    9    8    7    6    5    4    3     2     1     0
#> [4,]   14   10    9    8    7    6    5    4    3     2     1     0
#> [5,]   15   10    9    8    7    6    5    4    3     2     1     0

And that we have the correct dimensions:

dim(result)
#> [1] 646646     12
like image 27
Allan Cameron Avatar answered Jan 30 '23 04:01

Allan Cameron