Excel has a handy function that lets you set the y-intercept of an exponential regression model:

enter image description here

How can the same effect be achieved using R? I'm using the following code:

x <- c(...)
y <- c(...)

A <- structure(list(X=x, Y=y, .Names=c("X", "Y")))
exponential.model <- lm(log(Y) ~ 100 + X)
values <- seq(0, 100, 1)
Y.exponential2 <- exp(predict(exponential.model, list(X=values)))

plot(x, y2, main="Graph", pch=1, xlab="X", ylab="Y")
lines(values, Y.exponential, lty=1)

I'm trying to set the y-intercept to 100, but it's not doing that correctly. :(

  • 2
    $\begingroup$ In general one needs to set this up as a restricted optimization problem where there is a restriction for the intercept value (eg. $f(0)= 100$). You could use optim for that. For this particular case though just subtract $100$ from $\log(Y)$ and then fit a lm to the new variable with no intercept. $\endgroup$ – usεr11852 Feb 1 '16 at 17:21

As mentioned in the comment this is usually casted as a constrained optimization problem. This means that you could put a linear constraint such that when the values in X are of some particular value $x_0$ to give you back a particular number $y_0$. Nevertheless for your case as it is simply an intercept it can be easier to simply subtract a value. I wrote a small code snippet to show what I mean. I use a simple linear regression as a toy problem bu the mechanics are otherwise the same.

# Initialize the variable to use 
x1 = 1:100
x2 = sin(1:100)
e = rnorm(100)
y = 3*x1+ 2*x2 + 4 + e

OK, so here we somehow know that the intercept needs to be $4$. Let's do the simple linear regression first:

myLMbetas = coefficients( lm(y ~ x1 + x2) )
# (Intercept)          x1          x2 
# 3.970642       3.002369    1.879243 

The results for the intercept are close but not close enough... We proceed by defining our own cost function (in this case a simple RSS) and optimize this one:

myCost <- function(betas){ 
            return( sum((y - betas[1] - betas[2]*x1 - betas[3]*x2)^2) )
myOPTIMbetas = optim(par=runif(3), fn= myCost, method = 'L-BFGS-B')$par
# myOPTIMbetas
# [1] 3.970642 3.002369 1.879243

The results are the same as in LM above. No surprise there, we solve the same problem after all. But now we realize that we can constraint the value of some parameter to a range we like. We also realize that if the range is very small we essentially fix the parameter to a particular point. So we could something like that this:

myOPTIMbetas2 = optim(par=runif(3), fn= myCost, method = 'L-BFGS-B', 
                      lower= c(4,-Inf,-Inf), 
                      upper = c(4+4*.Machine$double.eps,Inf,Inf))$par
# myOPTIMbetas2
# [1] 4.000000 3.001930 1.878403

OK! This works. The reason we added a very small quantity in our upper bound (4*.Machine$double.eps) is to make sure we have differentiability. So this is $a$ solution. What about the fact we simply care about the intercept? Could we just NOT fit the intercept and take it as a given? Sure that is perfectly valid! Here you go:

myLMbetas = coefficients( lm(y -4 ~ -1 + x1 + x2) )
#       x1       x2 
# 3.001930 1.878403 

which again works. Another option would be to set this a non-linear regression problem and have this constraints embedded there. So something like:

nls( y ~ b0 + b1*x1 + b2*x2 , start=c(b0=4, b1=4, b2=4), algorithm = "port", 
     lower=c(b0=4, b1=-Inf, b2=-Inf), upper=c(b0=4, b1=Inf, b2= Inf))
Nonlinear regression model
  model: y ~ b0 + b1 * x1 + b2 * x2
   data: parent.frame()
   b0    b1    b2 
4.000 3.002 1.878 
 residual sum-of-squares: 81.25

Algorithm "port", convergence message: 
         both X-convergence and relative convergence (5)

Where now nls did essentially the same thing as we did above; it defined an optimization function, and solved it subjected to some particular constraints (using a different algorithm than optim). So this is it. Three different way to solve your problem in R. Notice that actually none of the three methods present really uses linear constraints. The two optimization problems just use a bounded parameter space. If you had a more complex constraint maybe you would not be able to such a simple solution and you would have to define proper linear constraints (eg. $\beta_1 x_1 + \beta_2 x_2 = c$, etc. etc.) but this is an overkill for this use case.


Not the answer you're looking for? Browse other questions tagged or ask your own question.