An Error in R: When I try to apply outer function:

前端 未结 1 657
抹茶落季
抹茶落季 2020-12-18 17:21

Here is my code: Step1: Define a inverse function which I will use later

inverse = function (f, lower = -100, upper = 100) {
  function (y) uniroot((function         


        
相关标签:
1条回答
  • 2020-12-18 18:12

    I believe it is a very commom misconception to assume that outer(x, y, FUN) calls the function parameter (FUN) once for each required pair x[i] and y[j]. Actually, outer calls FUN only once, after creating all possible pairs, combining every element of x with every element of y, in a manner similar to the function expand.grid.

    I'll show that with an example: consider this function, which is a wrapper for the product and print a message every time it's called:

    f <- function(x,y)
    {
        cat("f called with arguments: x =", capture.output(dput(x)), "y =", capture.output(dput(y)), "\n")
    
        x*y
    }
    

    This function is "naturally" vectorized, so we can call it with vector arguments:

    > f(c(1,2), c(3,4))
    f called with arguments: x = c(1, 2) y = c(3, 4) 
    [1] 3 8
    

    Using outer:

    > outer(c(1,2), c(3,4), f)
    f called with arguments: x = c(1, 2, 1, 2) y = c(3, 3, 4, 4) 
         [,1] [,2]
    [1,]    3    4
    [2,]    6    8
    

    Notice the combinations generated.

    If we can't guarantee that the function can handle vector arguments, there is a simple trick to ensure the function gets called only once for each pair in the combinations: Vectorize. This creates another function that calls the original function once for each element in the arguments:

    > Vectorize(f)(c(1,2),c(3,4))
    f called with arguments: x = 1 y = 3 
    f called with arguments: x = 2 y = 4 
    [1] 3 8
    

    So we can make a "safe" outer with it:

    > outer(c(1,2), c(3,4), Vectorize(f))
    f called with arguments: x = 1 y = 3 
    f called with arguments: x = 2 y = 3 
    f called with arguments: x = 1 y = 4 
    f called with arguments: x = 2 y = 4 
         [,1] [,2]
    [1,]    3    4
    [2,]    6    8
    

    In this case, the results are the same because f was written in a vectorized way, i.e., because "*" is vectorized. But if your function is not written with this in mind, using it directly in outer may fail or (worse) may give wrong results.

    0 讨论(0)
提交回复
热议问题