To find every vector of the form (x, y) where x is drawn from vector X and y from Y, we use expand.grid
:
X = c(1, 1, 2)
Y = c(4, 5)
expand.grid(X, Y)
# Var1 Var2
# 1 1 4
# 2 1 4
# 3 2 4
# 4 1 5
# 5 1 5
# 6 2 5
The result is a data.frame with one column for each vector passed to it. Often, we want to take the Cartesian product of sets rather than to expand a "grid" of vectors. We can use unique
, lapply
and do.call
:
m = do.call(expand.grid, lapply(list(X, Y), unique))
# Var1 Var2
# 1 1 4
# 2 2 4
# 3 1 5
# 4 2 5
If you then want to apply a function to each resulting combination f(x,y)
, it can be added as another column:
m$p = with(m, Var1*Var2)
# Var1 Var2 p
# 1 1 4 4
# 2 2 4 8
# 3 1 5 5
# 4 2 5 10
This approach works for as many vectors as we need, but in the special case of two, it is sometimes a better fit to have the result in a matrix, which can be achieved with outer
:
uX = unique(X)
uY = unique(Y)
outer(setNames(uX, uX), setNames(uY, uY), `*`)
# 4 5
# 1 4 5
# 2 8 10
For related concepts and tools, see the combinatorics topic.