Search code examples
rargumentsnlsnon-linear-regression

using R function nls with long list of variables


I am trying to estimate a non-linear model with the R function nls.

I will illustrate my problem with an example from the "help" facility for nls.

Treated <- Puromycin[Puromycin$state == "treated", ]
weighted.MM <- function(resp, conc, Vm, K)
{
    pred <- (Vm * conc)/(K + conc)
    (resp - pred) / sqrt(pred)
}

Pur.wt <- nls( ~ weighted.MM(rate, conc, Vm, K), data = Treated,
          start = list(Vm = 200, K = 0.1))

In this example, weighted.MM is a function with a very limited number of arguments, and I have no problem implementing analogous approaches for the type of model I am working with.

However, I am trying now to move to a more realistic problem, where I have literally dozens of arguments to pass on to the function. I could of course simply enumerate them, but I find this a bit unwieldy.

I have considered putting them in a separate list first. For instance, using the example from above, I would first define:

MyArguments <- list(Vm, K)  

and then passing MyArguments on as argument to the function (and accessing the individual arguments from within the function). However, that doesn't work, because I get the error message

Error: object 'Vm' not found

Alternatively,

    MyArguments <- list("Vm", "K") 

weighted.MM1 <- function(resp, conc1, conc.1, thearguments)
{
  conc <- c(conc1, conc.1)
  pred <- (thearguments[[1]] * conc)/(thearguments[[2]] + conc)
  (resp - pred) / sqrt(pred)
}

Pur.wt1 <- nls( ~ weighted.MM1(rate, conc1, conc.1, MyArguments),
                data = lisTreat, start = list(Vm = 200, K = 0.1))

yields:

Error in thearguments[[1]] * conc : 
  non-numeric argument to binary operator
Called from: weighted.MM1(rate, conc1, conc.1, MyArguments)

Is there any work-around for this?


Solution

  • Since you are looking for the values of your arguments, you do not need to define them: Look at the code below:

    weighted.MM1 <- function(resp, conc1, conc.1, thearguments)
    {
      conc <- c(conc1, conc.1)
      pred <- (thearguments[1] * conc)/(thearguments[2] + conc)
      (resp - pred) / sqrt(pred)
    }
    nls( ~ weighted.MM1(rate, conc1, conc.1, MyArguments),
                    data = lisTreat, start = list(MyArguments =c( 200, 0.1)))
    Nonlinear regression model
      model: 0 ~ weighted.MM1(rate, conc1, conc.1, MyArguments)
       data: lisTreat
    MyArguments1 MyArguments2 
       206.83468      0.05461 
     residual sum-of-squares: 14.6
    
    Number of iterations to convergence: 5 
    Achieved convergence tolerance: 3.858e-06