Search code examples
rnon-linear-regressionnls

Fitting complex non-linear function with nls() in R gives singular gradient error


I am trying to fit oral pharmacokinetic function using R nls. The function can be seen here: enter image description here

I tried the following:

dat <- data.frame(
        Time = c(10, 15, 20, 30, 40, 60, 90, 120, 180, 210, 240, 300, 360),
        C_PO = c(0,0.28,0.55,1.2,2,1.95,1.85,1.6,
                 0.86,0.78,0.6,0.21,0.18))

plot(dat$C_PO ~ dat$Time, data = dat, log = "y")

fit <- nls(C_PO~ka*100* (exp(-k*Time) - exp(-ka*Time))/(v*(ka- k)),
    data = dat,
    start = list(ka = 0.09, k = 0.01, v = 50))
#> Error in nls(C_PO ~ ka * 100 * (exp(-k * Time) - exp(-ka * Time))/(v * : singular gradient

The code is trying to fit a non-linear model according to the concentration values C_PO over a time period Time. The initial values were calculated using graph stripping methods. However, the error message reads "singular gradient." How can this be fixed?


Solution

  • You can use gslnls package for fitting non-linear model like

    library(gslnls)
    
    dat <- data.frame(
      Time = c(10, 15, 20, 30, 40, 60, 90, 120, 180, 210, 240, 300, 360),
      C_PO = c(0,0.28,0.55,1.2,2,1.95,1.85,1.6,
               0.86,0.78,0.6,0.21,0.18))
    
    plot(dat$C_PO ~ dat$Time, data = dat, log = "y")
    
    fit <- gsl_nls(C_PO ~ ka*100* (exp(-k*Time) - exp(-ka*Time))/(v*(ka- k)), 
                        data = dat, 
                        start = c(ka = 0.09, k = 0.01, v = 50), 
                        control = gsl_nls_control(maxiter = 500))
    
    summary(fit)
    
    #> Formula: C_PO ~ ka * 100 * (exp(-k * Time) - exp(-ka * Time))/(v * (ka - 
    #>     k))
    #> 
    #> Parameters:
    #>     Estimate Std. Error t value Pr(>|t|)
    #> ka    0.0132     4.0027   0.003    0.997
    #> k     0.0132     4.0025   0.003    0.997
    #> v    21.0181  6372.7704   0.003    0.997
    #> 
    #> Residual standard error: 0.3363 on 10 degrees of freedom
    #> 
    #> Number of iterations to convergence: 18 
    #> Achieved convergence tolerance: 0