r/rstats 8d ago

4PL NLS Help

I'm very new to R so might be making some very obvious mistakes, any help is appreciated! I know at least the numbers work because I manually entered them into an actual 4PL calculator.

I have this code:

fit <- nls(OD ~ D + (A - D)/(1 + (Concentration/C)^B),
           data = stand_mean,
           start = list(A = max(stand_mean$OD), D = min(stand_mean$OD), C = median(stand_mean$Concentration), B = 1))

giving this error

Error in numericDeriv(form[[3L]], names(ind), env, central = nDcentral) :
Missing value or an infinity produced when evaluating the model
2 Upvotes

8 comments sorted by

1

u/doughfacedhomunculus 8d ago

The nls function is notoriously brittle and susceptible to failure without reasonable start parameters. You could try some other packages with different optimisation algorithms? See:  https://journal.r-project.org/articles/RJ-2023-091/

1

u/SalvatoreEggplant 7d ago

One thing is to try another fitting algorithm. The following uses the Levenberg–Marquardt method. I have some notes at the bottom the page at: https://rcompanion.org/handbook/I_11.html

# Example from: https://rcompanion.org/handbook/I_11.html

if(!require(minpack.lm)){install.packages("minpack.lm")}
if(!require(rcompanion)){install.packages("rcompanion")}

library(rcompanion)

data("BrendonSmall")

library(minpack.lm)

D       = 1974

expon = function(x, a, b, c) {
 a + b * exp(-1 * c * (x - D))}

model = nlsLM(Sodium ~ expon(Calories, a, b, c),
              data = BrendonSmall,
              start = list(a = 1400,
                           b = -1,
                           c = 0.1))

summary(model)

1

u/SalvatoreEggplant 7d ago edited 7d ago

P.S. there is also the nlmrt package. ( https://cran.r-project.org/web/packages/nlmrt/index.html ). This used to work really well. But last I tried it, it wouldn't work on newer versions of R. It might be worth it to run it with an old version of R.

2

u/Ok_Customer_4058 7d ago

Thanks for all the info!!

1

u/SalvatoreEggplant 7d ago

Another thing to try is to find better initial estimates of the parameters, especially if you have more than a couple of parameters.

This is difficult to explain, but what I do is set up an Excel sheet where I have a bunch of data, and cells for the parameters, and the predicted y based on these. It's all hot-linked, so I as change the parameter estimates, the y values change.

I then have a plot hot-linked to the data. So as I change the parameters, the plot changes. You'll be able to get really good initial estimates for the parameters as you see what will actually make the line fit the data.