How to Compare Two Negative Exponential Growth Models? – Multivariate Analysis and Nonlinear Regression

interactionmultivariate analysisnonlinear regressionr

I have two negative exponential growth models which I want to compare in respect of the overall slope of the fitted regression lines (are the two lines significant different?). Below an image of the two models and the underlying data (model m1[black], model m2[red]):
enter image description here

Below is the reproducible code in R.

(a) Example data:

time <- rep(c(rep(0,7),7.1,rep(9.4,2),rep(25.6,3),rep(46,4),rep(106,5),rep(160,6)),2)
group <- rep(c("A","B"), each=28)
intensity <- c(0.026, 0.043, 0.035, 0.027, 0.031, 0.041, 0.053, 0.088, 0.120, 0.152, 0.229, 
    0.215, 0.243, 0.346, 0.327, 0.303, 0.311, 0.367, 0.373, 0.368, 0.367, 0.428, 0.434, 
    0.434, 0.408, 0.409, 0.390, 0.438, 0.035, 0.036, 0.036, 0.039, 0.033, 0.030, 0.047, 
    0.227, 0.251, 0.282, 0.324, 0.301, 0.317, 0.417, 0.432, 0.399, 0.408, 0.508, 0.517, 
    0.502, 0.497, 0.529, 0.536, 0.528, 0.543, 0.541, 0.570, 0.546)
data <- data.frame(time=time, intensity=intensity, group=group)

(b) Negative exponential growth model:

getModel <- function(df){

    nl_model <- function(a, b, c, x){

        y = a * exp(c * x) + b * (1 - exp(c * x))
        return(y)
    }

    x_grid <- seq(0, 160, length = 200)  ## prediction grid

    mcoeff <- nls(intensity ~ a * exp(time * c) + b * (1-(exp(time * c))), 
        start = list(a = 0.01, b = 0.5, c = -0.01), data = df, 
        control = list(maxiter = 500))

    coeff <- as.data.frame(summary(mcoeff)["coefficients"])

    y_pred <- data.frame(intensity = do.call(rbind, lapply(x_grid, nl_model, 
        a = coeff["a",1], b = coeff["b",1], c = coeff["c",1])))

    model_coord <- data.frame(time = x_grid, y_pred)
}

m1 <- getModel(subset(data, group=="A"))
m2 <- getModel(subset(data, group=="B"))

(c) Visualisation:

plot(subset(data, group=="A")$time, subset(data, group=="A")$intensity, col="black", 
    ylim=c(0,0.575), xlab="time", ylab="intensity")
points(subset(data, group=="B")$time, subset(data, group=="B")$intensity, col="red")
lines(m1$time, m1$intensity, type = "l", col = "black", lwd=1.5)
lines(m2$time, m2$intensity, type = "l", col = "red", lwd=1.5)

I read the following posts What test can I use to compare slopes from two or more regression models? + How to calculate the difference of two slopes? and understand how to compare the slopes of two linear models. I wonder if something similar could be done with the negative exponential growth model? I also know that I can compute the overall slope value of a regression line by predicting y values using the model and a reference grid. But this would just give me a single mean slope value for each model, not sufficient for any statistical test. I would also be happy to directly use the input values for test statistics, any suggestions which test could be applied in this context would be very helpful, too.

Best Answer

The way I'd approach this problem is similar to the answers you've already linked.

First, I'd fit a model that constrains the $a$, $b$, and $c$ parameters to be the same regardless of the group, along with another model that estimates separate parameters by group, and then run an F test to compare them.

The nls formula allows you to define some parameters to vary by groups using the parameter[group] syntax. For example:

# Convert group to factor 
df <- data.frame(time = time, 
                 intensity = intensity, 
                 group = as.factor(group))

# Denote start values
start_vals <- list(a = 0.01, b = 0.5, c = -0.01)

# Fit null model - equal a, b, and c parameters for each group
m0 <- nls(intensity ~ a * exp(time * c) + b * (1-(exp(time * c))), 
          start = start_vals,
          data = df)

# Fit model with differing a, b, and c parameters by group
m1 <- nls(intensity ~ a[group] * exp(time * c[group]) + b[group] * (1-(exp(time * c[group]))), 
          start = lapply(start_vals, rep, 2), 
          data = df)

# Compare with F-test
anova(m0, m1)

For the data you provided we find:

Analysis of Variance Table

Model 1: intensity ~ a * exp(time * c) + b * (1 - (exp(time * c)))
Model 2: intensity ~ a[group] * exp(time * c[group]) + b[group] * (1 - (exp(time * c[group])))
  Res.Df Res.Sum Sq Df  Sum Sq F value    Pr(>F)    
1     53   0.169120                                 
2     50   0.037145  3 0.13198  59.217 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Note that this is a joint test for equality of all the parameters defining the slopes - it is possible that you may have reason to constrain one or more parameters to be the same across groups (e.g., fixing $a$, which corresponds to the starting value, across groups), or isolate parameters (e.g., determine whether $b$ alone differs by group). You'd just need to adjust the code above accordingly.

Related Question