Lisa Ann
Lisa Ann

Reputation: 3485

About the use and the output of outer()

Please, run the following reproducible code:

require(compiler)

a <- 1:80
n <- 1:140

fn <- cmpfun(function(a, n)
{
  K <- ceiling(runif(n, min = 1, max = 80))
  p <- length(K[K >= min(80, a + 5)]) / n
  return(p)
})

It is sure the fn() function returns a number smaller than 1, due to the fact that it should return the frequency of the random numbers from K which are greater than a + 5; this can be verified with random integer inputs in fn():

for(i in seq(8, 80, 8))
{
  for(j in seq(14, 140, 14))
  {
    print(fn(i,j))
  }
}

Now I would like to get the cross-function of fn() applied to a and n arrays, and I thought outer() was the best solution:

The outer product of the arrays X and Y is the array A with dimension c(dim(X), dim(Y)) where element A[c(arrayindex.x, arrayindex.y)] = FUN(X[arrayindex.x], Y[arrayindex.y], ...).

I would expect to get output from 0 to 1 but

persp(x = a, y = n, z = outer(X = a, Y = n, FUN = fn), 
      ticktype = 'detailed', phi = 30, theta = 120)

does return this output, instead:

enter image description here

What I am missing in the use of outer()?

Upvotes: 0

Views: 52

Answers (2)

plannapus
plannapus

Reputation: 18749

As @Roland said, the function you need to input to outer need to be vectorized first. One way of doing this:

fn_vec <- Vectorize(fn)
outer(a,n,fn_vec)

Upvotes: 1

Roland
Roland

Reputation: 132706

length(K[K >= min(80, a + 5)]) isn't what you think it is. outer needs a function, which is vectorized in both parameters. Your function is vectorized by chance, but not in the way you want.

Look at this:

set.seed(42)
n <- 1:5
x <- runif(n, min = 1, max = 80)
#[1] 73.26968 75.02896 23.60502 66.60536 51.69790
x/n
#[1] 73.269677 37.514479  7.868341 16.651341 10.339579

Upvotes: 2

Related Questions