Solved – nls curve fitting of nested/shared parameters

curve fittingnlsnonlinear regressionr

I'm trying to fit raw data to curves, which works well on an individual basis. However, I'd like to "share" parameters (sometimes referred as nested parameters) across more than one data series. Is there a way to do this in R?

Best Answer

If the error variance is also common across data series, the usual way to do such a thing is to "stack" the y's and set up predictors (modified versions of x) so that the parameters that are not in common 'zero out'/remove the effect of the parameters that don't apply to the particular subset.

Here's an example of fitting a model of the form $y = a +$ $\exp$$(b + c x) + e$ to two data sets, and then in a combined fit with a common $c$ parameter.

# create data:
a1 <- -0.82e-2; b1 <-  3.8e-3; c1 <- 9.e-2
a2 <-  2.20e-2; b2 <- -1.3e-3; c2 <- c1

x1 <-  1:10
x2 <-  6:14

n1 <- length(x1)
n2 <- length(x2)

e1 <- c(0.109, 0.511, 1.243, 0.978, -0.584, 1.377, 0.292, -0.897, -0.411, -0.878)
e2 <- c(-0.343, 0.818, -0.059, -0.471, -0.194, -0.398, -1.535,  1.093, -0.721)
sig <- 2.e-3

y1 <-  a1+exp(b1+c1*x1)+sig*e1
y2 <-  a2+exp(b2+c2*x2)+sig*e2

#plot data
plot(x1,y1)
points(x2,y2,col=2)

# separate fits:  
nls(y1 ~ a1 + exp(b1+c1*x1), start=list(a1=0,b1=4e-3,c1=1e-1))
nls(y2 ~ a2 + exp(b2+c2*x2), start=list(a2=0,b2=-1e-3,c2=1e-1))

#set up stacked variables:
y <- c(y1,y2); x <- c(x1,x2)

lcon1 <- rep(c(1,0), c(n1,n2))
lcon2 <- rep(c(0,1), c(n1,n2))
mcon1 <- lcon1
mcon2 <- lcon2

# combined fit with common 'c' parameter, other parameters separate
nls(y ~ a1*lcon1 + a2*lcon2 + exp(b1*mcon1 + b2*mcon2 + cc * x),
       start = list(a1=0,a2=0,b1=4e-3,b2=-1e-3,cc=1e-1))
Related Question