I have a function of two scalar values x_i, y_j. I have a vector of n x_i values, X and n y_j values, e.g.
myfunction <- function(x,y) min(x,y)
X <- 1:3
Y <- 2:4
I want to fill out the $n$ by $n$ matrix whose elements (i,j) are given by myfunction(x_i, y_j). There’s a lot of ways to do this in R, and I’m curious about their relative performance.
For instance, this seems like a task for outer, but it seems to get confused whether it is passing a vector or scalar to myfunction. First consider:
r
outer(X, Y, paste)
gives me each of the pairs
[,1] [,2] [,3]
[1,] "1 2" "1 3" "1 4"
[2,] "2 2" "2 3" "2 4"
[3,] "3 2" "3 3" "3 4"
Looks good. But
outer(X, Y, myfunction)
throws the error:
Error: dims [product 9] do not match the length of object [1]
Meanwhile other possible functions seem to behave as I expected with scalars, such as:
myfunction <- function(x,y) exp((x-y)^2)
which works fine
outer(X, Y, myfunction)
[,1] [,2] [,3]
[1,] 2.718282 54.598150 8103.083928
[2,] 1.000000 2.718282 54.598150
[3,] 2.718282 1.000000 2.718282
In a few quick numerical experiments, it seems this is slightly faster than expand.grid, and the function call more compact, but I don’t seem to understand why some functions appear to work as I anticipate and others do not.
The classic expand.grid solution also requires the function to work with vector arguments, which means a very different thing for my example with min; a different version of the same problem. Is there a way to enforce the fact that the arguments to my function must be scalars rather than vectors?
The function passed to outer must be vectorized,
From the source code
minwill return a single number, you would wantpmin.More generally you could use Vectorize.