# How to calculate the product from combinations of several vectors in R?

• A+
Category：Languages

I feel it hard to give an accurate title, though I have tried my best. Here's my problem.

``a = 1/(1:10) b = 3/(1:10) c = 1/(1:5) d = 1/(1:11) ``

I would like to get a vector `e`, such that `e` consists of the product calculated from the combinations of values chosen from `a`, `b`, `c` and `d`.

For example, supposing there are two vectors `{1, 2}` and `{3, 4}`, I would like to get a vector like this `{1 * 3, 1 * 4, 2 * 3, 2 * 4} = {3, 4, 6, 8}`.

The `expand.grid` solution is OK, but in mathematics there is an elegant Kronecker product.

R has a function `kronecker`, but it takes two vectors at a time, so we need `Reduce` for a recursive application:

``oo <- Reduce(kronecker, list(a, b, c, d)) ``

Alternatively, use `outer` (the workhorse of `kronecker`):

``rr <- Reduce(outer, list(a, b, c, d)) ``

This is more user-friendly, as `rr[i, j, u, v]` gives you `a[i] * b[j] * c[u] * d[v]`.

Remark 1

Note that elements in `oo` and `rr` differ in order. Because for two vectors `a` and `b`:

``kronecker(a, b)  ## a * b, a * b ... outer(a, b)      ## a * b, a * b ... ``

Thus the following use of `kronecker` produces a result identical to `rr`.

``zz <- Reduce(kronecker, list(d, c, b, a)) dim(zz) <- c(length(a), length(b), length(c), length(d)) ``

Remark 2

The method can be adapted to do `a[i] + b[j] + c[u] + d[v]`, by replacing the default operation `"*"` in `outer` and `kronecker` to `"+"`. For example:

``Reduce(function (x, y) outer(x, y, "+"), list(a, b, c, d)) ``

Remark 3

johannes's answer can be improved. That row-wise application of `apply` is a performance killer. We can do the following to get a result consistent with `rr`.

``xx <- Reduce("*", expand.grid(a, b, c, d)) dim(xx) <- c(length(a), length(b), length(c), length(d)) ``