expand.grid
is a very handy function in R
for calculating all possible combinations of several list. Here is how it works:
> x = c(1,2,3)
> y = c("a","b")
> z = c(10,12)
> d = expand.grid(x,y,z)
> d
Var1 Var2 Var3
1 1 a 10
2 2 a 10
3 3 a 10
4 1 b 10
5 2 b 10
6 3 b 10
7 1 a 12
8 2 a 12
9 3 a 12
10 1 b 12
11 2 b 12
12 3 b 12
How can I reproduce this function in Julia?
What is the expand.grid () function? It is a function in R’s Base system, meaning that it is already there when you install R for the first time, and does not even require any additional package to be installed. From the function’s documentation, it “Create a Data Frame from All Combinations of Factor Variables”.
From the function’s documentation, it “Create a Data Frame from All Combinations of Factor Variables”. There is also a more recent adaptation of it into a tidyr::expand_grid () one, which takes care of some annoying side effects, and also allows expanding data.frames.
For example, ggplot R commands such as don’t translate directly to Julia code because the . in na.rm is interpreted as Julia syntax. Similar issues arise if, for instance, an R function uses end as an argument name. The solution to this problem is to use the var string macro provided by RCall, which enables us to write
For example, ggplot R commands such as don’t translate directly to Julia code because the . in na.rm is interpreted as Julia syntax. Similar issues arise if, for instance, an R function uses end as an argument name.
Thanks to @Henrik's comment:
x = [1,2,3]
y = ["a","b"]
z = [10,12]
d = collect(Iterators.product(x,y,z))
Here is another solution using list comprehension
reshape([ [x,y,z] for x=x, y=y, z=z ],length(x)*length(y)*length(z))
Here is my completely(?) general solution, using recursion, varargs, and splatting:
function expandgrid(args...)
if length(args) == 0
return Any[]
elseif length(args) == 1
return args[1]
else
rest = expandgrid(args[2:end]...)
ret = Any[]
for i in args[1]
for r in rest
push!(ret, vcat(i,r))
end
end
return ret
end
end
eg = expandgrid([1,2,3], ["a","b"], [10,12])
@assert length(eg) == 3*2*2
@show eg
This gives an array of arrays, but you could combine that into a matrix trivially if thats what you wanted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With