- A+

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}`

.

Thanks in advance!

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[1] * b, a[2] * b ... outer(a, b) ## a * b[1], a * b[2] ... `

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)) `