Dynamic arguments to expand.grid
Asked Answered
C

3

8

I am using expand.grid to generate all of the pairs of the elements of a vector, such as:

v <- 1:3
expand.grid(v,v)

Which gives:

  Var1 Var2
1    1    1
2    2    1
3    3    1
4    1    2
5    2    2
6    3    2
7    1    3
8    2    3
9    3    3

Now, say I want the same thing but with triplets I use

expand.grid(v,v,v)

How would I go about generalizing this to n-tuples so that I can use new.expand.grid(v,5) and have the result of expand.grid(v,v,v,v,v)?

Colleague answered 16/10, 2013 at 17:13 Comment(0)
L
16

expand.grid can take a list as its input, so what about replicate?

expand.grid(replicate(3, v, simplify=FALSE))

For fun, as a function (though I know you would know how to do this):

new.expand.grid <- function(input, reps) {
  expand.grid(replicate(reps, input, simplify = FALSE))
}

new.expand.grid(c(1, 2), 4)
#    Var1 Var2 Var3 Var4
# 1     1    1    1    1
# 2     2    1    1    1
# 3     1    2    1    1
# 4     2    2    1    1
# 5     1    1    2    1
# 6     2    1    2    1
# 7     1    2    2    1
# 8     2    2    2    1
# 9     1    1    1    2
# 10    2    1    1    2
# 11    1    2    1    2
# 12    2    2    1    2
# 13    1    1    2    2
# 14    2    1    2    2
# 15    1    2    2    2
# 16    2    2    2    2
Leenaleeper answered 16/10, 2013 at 17:15 Comment(1)
Great! I did not really think about doing it this way!Colleague
S
6

do.call is the standard way of passing a dynamic set of arguments to a function:

new.expand.grid <- function(vec,nrep) do.call(expand.grid,rep(list(vec),nrep))

Example: new.expand.grid(letters[1:2],4)

   Var1 Var2 Var3 Var4
1     a    a    a    a
2     b    a    a    a
3     a    b    a    a
4     b    b    a    a
5     a    a    b    a
6     b    a    b    a
7     a    b    b    a
8     b    b    b    a
9     a    a    a    b
10    b    a    a    b
11    a    b    a    b
12    b    b    a    b
13    a    a    b    b
14    b    a    b    b
15    a    b    b    b
16    b    b    b    b
Stadiometer answered 16/10, 2013 at 17:34 Comment(2)
Point taken about do.call, but I think it is overkill in this case. expand.grid(rep(list(v), 4)) would be sufficient. I would guess that benchmarking just the rep vs replicate part of our answers, one would find the rep approach to be faster.Leenaleeper
@AnandaMahto Yeah, I was just thinking about how to construct the exact call the OP mentioned, instead of, you know, giving the most useful answer. :)Stadiometer
F
2

I think the simplest (and shortest) solution is the following:

expand.grid(rep(list(1:3), 2)) 
  Var1 Var2
1    1    1
2    2    1
3    3    1
4    1    2
5    2    2
6    3    2
7    1    3
8    2    3
9    3    3
Foreconscious answered 29/4, 2019 at 11:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.