Search code examples
rnlsnested-function

nls2 with nested functions


I am trying to find parameters using the nls2 package. As the formula I am trying to optimize parameters for is quite complex, I try to use functions that I call within the formula I optimize with the nls2 command:

library(nls2)

set.seed(20160227)
x <- seq(0,50,1)
y <- ((runif(1,10,20)*x)/(runif(1,0,10)+x))+rnorm(51,0,1)

a <- function(){
d+1
}

f1 <- function(){
y <- a()*x/(b+x)
}

st <- data.frame(d = c(-100,100),
                 b = c(-100,100))

nls2(f1,start = st, algorithm = "brute-force")

Currently, this throws the error

Error: object of type 'closure' is not subsettable

I found this error here, however when I assign values to b and d this works:

 a()*x/(b+x)

I assume the problem is that I try to find b and d using functions that already have them inside?

What is the best way to do this? Is it even possible or do I need to define the entire complex formula within nls2?


Solution

  • Neither f1 nor a here have any parameters, so it's not really surprising that it's having some difficulty understanding how you want to optimize f1.

    nls2::nls2 (like stats::nls) expects a formula as the first parameter. That formula can be built from any function you want, and does not have to be written down entirely in the call. You could do the following:

    a <- function(d){
      d+1
    }
    
    f1 <- function(b,d,x){
      y <- a(d)*x/(b+x)
    }
    

    And then fit the model like this:

    nls2(y~f1(b,d,x), start = st, algorithm = "brute-force")
    

    Because no start value is provided for x, and because its actual value can be found in the environment, it won't optimize over x, just b and d.