Reputation: 633
The following structure is given:
a <- list()
a[[1]] <- list(c(1:3),c(3:8))
a[[2]] <- list(c(2:6),c(7:9),c(18:24))
a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))
That means a[[1]]
has 2 elements, a[[2]]
3 elements and a[[3]]
5 elements.
I would like to create all the possible combinations from the elements within a.
So for example a[[1]][1]
can be combined with a[[2]][1]
,a[[2]][2]
and a[[2]][3]
. All of those results can be combined with a[[3]][1]
,...,a[[3]][5]
(All in all it should be 30 combinations). By combining I mean applying c
to the elements.
I assume this comes down to searching elements at the end of a tree (e.g. if I have A1 or A2 in phase 1, B1 or B2 in phase 2 and C1 or C2 in phase 3, all results would be: A1B1C1, A1B1C2, A1B2C1, A1B2C2, A2B1C1, A2B1C2, A2B2C1, A2B2C2.)
Ok now I know how to do this with a triple nested loop, but what happens if list a becomes larger? I don't know if it can be done otherwise though. Any suggestions appreciated.
Upvotes: 0
Views: 201
Reputation: 7287
Use expand.grid {base}
:
a <- list()
a[[1]] <- list(c(1:3),c(3:8))
a[[2]] <- list(c(2:6),c(7:9),c(18:24))
a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))
comb <- expand.grid(a)
Upvotes: 5
Reputation: 193517
As an alternative to expand.grid
, if you are looking for more speed as the lists grow, you can check out CJ
from the "data.table" package:
The approach would be:
library(data.table)
do.call(CJ, a)
Here are the first few rows:
> head(do.call(CJ, a), 10)
V1 V2 V3
1: 1,2,3 2,3,4,5,6 11,12,13
2: 1,2,3 2,3,4,5,6 10,11,12,13,14,15,
3: 1,2,3 2,3,4,5,6 17,18,19
4: 1,2,3 2,3,4,5,6 11,12,13,14
5: 1,2,3 2,3,4,5,6 17,18,19,20
6: 1,2,3 7,8,9 11,12,13
7: 1,2,3 7,8,9 10,11,12,13,14,15,
8: 1,2,3 7,8,9 17,18,19
9: 1,2,3 7,8,9 11,12,13,14
10: 1,2,3 7,8,9 17,18,19,20
(The do.call
approach would also work with expand.grid
).
Quick comparison:
a <- list()
a[[1]] <- list(c(1:3),c(3:8))
a[[2]] <- list(c(2:6),c(7:9),c(18:24))
a[[3]] <- list(c(11:13),c(10:16),c(17:19),c(11:14),c(17:20))
## 15 item list
a <- unlist(replicate(5, a, FALSE), recursive = FALSE)
system.time(do.call(expand.grid, a))
# user system elapsed
# 8.020 2.232 10.254
system.time(do.call(CJ, a))
# user system elapsed
# 2.180 0.828 3.004
Upvotes: 3