ash_sak
ash_sak

Reputation: 11

Model fitting with nls.lm in R, "Error: unused argument"

I'm trying to use the nls.lm function in the minpack.lm to fit a non-linear model to some data from a psychophysics experiment.

I've had a search around and can't find a lot of information about the package so have essentially copied the format of the example given on the nls.lm help page. Unfortunately my script is still failing to run and R is throwing out this error:

Error in fn(par, ...) : 
unused argument (observed = c(0.1429, 0.2857, 0.375, 0.3846, 0.4667, 0.6154))

It appears that the script thinks the data I want to fit the model to is irrelevant, which is definitely wrong.

I'm expecting it to fit the model and produce a value of 0.5403 for the spare parameter (w).

Any help is greatly appreciated. I'm making the transfer from Matlab over to R so apologies if my code looks sloppy.

Here's the script.

  install.packages("pracma")
  require(pracma)
  install.packages("minpack.lm")
  require(minpack.lm)

  # Residual function, uses parameter w (e.g. .23) to predict accuracy error at a given ratio [e.g. 2:1]
  residFun=function(w,n) .5 * erfc( abs(n[,1]-n[,2])/ ((sqrt(2)*w) * sqrt( (n[,1]^2) + (n[,2]^2) ) ) )

  # example for residFun
  # calculates an error rate of 2.59%
  a=matrix(c(2,1),1,byrow=TRUE)
  residFun(.23,a)

  # Initial guess for parameter to be fitted (w)
  parStart=list(w=0.2)

  # Recorded accuracies in matrix, 1- gives errors to input into residFun
  # i.e. the y-values I want to fit the model
  Acc=1-(matrix(c(0.8571,0.7143,0.6250,0.6154,0.5333,0.3846),ncol=6))

  # Ratios (converted to proportions) used in testing
  # i.e. the points along the x-axis to fit the above data to
  Ratios=matrix(c(0.3,0.7,0.4,0.6,0.42,0.58,0.45,0.55,0.47,0.53,0.49,0.51),nrow=6,byrow=TRUE)

  # non-linear model fitting, attempting to calculate the value of w using the Levenberg-Marquardt nonlinear least-squares algorithm 
  output=nls.lm(par=parStart,fn=residFun,observed=Acc,n=Ratios)

  # Error message shown after running
  # Error in fn(par, ...) : 
  #   unused argument (observed = c(0.1429, 0.2857, 0.375, 0.3846, 0.4667, 0.6154))

Upvotes: 1

Views: 5761

Answers (1)

scoa
scoa

Reputation: 19857

The error means you passed a function an argument that it did not expect. ?nls.lm has no argument observed, so it is passed to the function passed to fn, in your case, residFun. However, residFun doesn't expect this argument either, hence the error. You need to redefine this function like this :

# Residual function, uses parameter w (e.g. .23) to predict accuracy error at a given ratio [e.g. 2:1]
residFun=function(par,observed, n) {
  w <- par$w
  r <- observed - (.5 * erfc( abs(n[,1]-n[,2])/ ((sqrt(2)*w) * sqrt( (n[,1]^2) + (n[,2]^2) ) ) ))
  return(r)
}

It gives the following result :

> output = nls.lm(par=parStart,fn=residFun,observed=Acc,n=Ratios)
> output
Nonlinear regression via the Levenberg-Marquardt algorithm
parameter estimates: 0.540285874836135 
residual sum-of-squares: 0.02166
reason terminated: Relative error in the sum of squares is at most `ftol'.

Why that happened :

It seems that you were inspired by this example in he documentation :

## residual function
residFun <- function(p, observed, xx) observed - getPred(p,xx)
## starting values for parameters
parStart <- list(a=3,b=-.001, c=1)
## perform fit
nls.out <- nls.lm(par=parStart, fn = residFun, observed = simDNoisy,
xx = x, control = nls.lm.control(nprint=1))

Note that observed is an argument of residFun here.

Upvotes: 2

Related Questions