Reputation: 43
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?
Upvotes: 4
Views: 286
Reputation: 174536
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
Upvotes: 3
Reputation: 34763
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))
Upvotes: 5