45

I want to calculate a linear regression using the lm() function in R. Additionally I want to get the slope of a regression, where I explicitly give the intercept to lm().

I found an example on the internet and I tried to read the R-help "?lm" (unfortunately I'm not able to understand it), but I did not succeed. Can anyone tell me where my mistake is?

lin <- data.frame(x = c(0:6), y = c(0.3, 0.1, 0.9, 3.1, 5, 4.9, 6.2))
plot (lin$x, lin$y)

regImp = lm(formula = lin$x ~ lin$y)
abline(regImp, col="blue")

# Does not work:
# Use 1 as intercept
explicitIntercept = rep(1, length(lin$x))
regExp = lm(formula = lin$x ~ lin$y + explicitIntercept)
abline(regExp, col="green")

Thanls for your help.

Zheyuan Li
  • 71,365
  • 17
  • 180
  • 248
R_User
  • 10,682
  • 25
  • 79
  • 120

3 Answers3

48

You could subtract the explicit intercept from the regressand and then fit the intercept-free model:

> intercept <- 1.0
> fit <- lm(I(x - intercept) ~ 0 + y, lin)
> summary(fit)

The 0 + suppresses the fitting of the intercept by lm.

edit To plot the fit, use

> abline(intercept, coef(fit))

P.S. The variables in your model look the wrong way round: it's usually y ~ x, not x ~ y (i.e. the regressand should go on the left and the regressor(s) on the right).

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 5
    or `I(x - 1.0)~ y-1` surpresses the fitting of the intercept as well. – Joris Meys Sep 07 '11 at 11:47
  • 2
    @Joris Meys: Yes. I believe the two ways are synonymous. I chose the other way to avoid having two `-1` terms and having to explain which is which. – NPE Sep 07 '11 at 11:48
  • But when I plot the regression-curve abline(regExp, col="green"), it does not go through 1. I have not figured out how to extract the slope (and/or intercept) from the lm ouput. For mee it seems that you always have to know the position of the values in the coef-array, and than extract in (and hope that the position is right). So, is the following code the "golden way" to plot the correct regression curve? `abline(b=coef(regExp)[1], a= explicitIntercept, col="green")` – R_User Sep 07 '11 at 12:20
  • @Sven: `abline(1.0, coef(fit))` plots the fit (here, 1.0 is the explicit intercept). I've updated the answer to include this. – NPE Sep 07 '11 at 12:36
  • 2
    See also the `offset` argument. – Aaron left Stack Overflow Sep 07 '11 at 13:20
  • `offset` can be used either as an argument or as a term in the model. (You were posting your comment as the same time as I was offering an alternate answer.) – IRTFM Sep 07 '11 at 13:31
  • `fit = lm(x~0+y, lin)` will have the effect of forcing the line through the origin then? Thanks. – qed Apr 17 '13 at 11:31
  • @qed, no, `y - 1` will. Try `abline(lm(x ~ y - 1, data=lin))`. – Roman Luštrik Apr 24 '14 at 08:33
22

I see that you have accepted a solution using I(). I had thought that an offset() based solution would have been more obvious, but tastes vary and after working through the offset solution I can appreciate the economy of the I() solution:

with(lin, plot(y,x) )
lm_shift_up <- lm(x ~ y +0 + 
                       offset(rep(1, nrow(lin))), 
             data=lin)
abline(1,coef(lm_shift_up))
IRTFM
  • 258,963
  • 21
  • 364
  • 487
1

I have used both offset and I(). I also find offset easier to work with (like BondedDust) since you can set your intercept.

Assuming Intercept is 10.

plot (lin$x, lin$y) fit <-lm(lin$y~0 +lin$x,offset=rep(10,length(lin$x))) abline(fit,col="blue")