Reputation: 60
Say I have 2 (or more) vectors:
v1 <- letters[1:2]
v2 <- letters[24:26]
> v1
[1] "a" "b"
> v2
[1] "x" "y" "z"
How could I programmatically construct a nested list like this, that contains lists of all of the combinations of my input vectors? Edit: I'd like to do this without inefficient looping structures.
> l1 <- list(list(v1[1], v2[1]), list(v1[1], v2[2]),
list(v1[1], v2[3]), list(v1[2], v2[1]),
list(v1[2], v2[2]), list(v1[2], v2[3]))
> str(l1)
List of 6
$ :List of 2
..$ : chr "a"
..$ : chr "x"
$ :List of 2
..$ : chr "a"
..$ : chr "y"
$ :List of 2
..$ : chr "a"
..$ : chr "z"
$ :List of 2
..$ : chr "b"
..$ : chr "x"
$ :List of 2
..$ : chr "b"
..$ : chr "y"
$ :List of 2
..$ : chr "b"
..$ : chr "z"
Upvotes: 1
Views: 277
Reputation: 33743
A simple way is to use loops:
l1 <- list()
list_pos <- 1L
for (i in 1:length(v1)) {
for (j in 1:length(v2)) {
l1[[list_pos]] <- list(v1[i], v2[j])
list_pos <- list_pos + 1L
}
}
Edit:
I think loops get a bit of unfair rep but here is some (ugly) code that avoids them:
l2 <- apply(expand.grid(v1, v2), 1, as.list)
Btw. The loop is way faster. I suspect there are some much prettier and more creative ways to do this still.
Upvotes: 1
Reputation: 10875
Here is a solution that generates the required combinations into a data frame.
> v1 <- letters[1:2]
> v2 <- letters[24:26]
>
> aResult <- expand.grid(v2,v1)
> View(aResult)
> aResult
Var1 Var2
1 x a
2 y a
3 z a
4 x b
5 y b
6 z b
>
If the data frame must be split into a list()
of one combination per list entry, we can accomplish this with split()
.
#If the data frame must be split into a list, one entry per row
aResult$id <- as.factor(1:nrow(aResult))
theList <- split(aResult,aResult$id)
Printing the first element in the list, we see the following.
> theList[[1]]
Var1 Var2 id
1 x a 1
>
Upvotes: 1