Re: [Rd] abline for intercept-only simple lm models (with and without offset)

From: Martin Maechler <>
Date: Mon 18 Dec 2006 - 11:29:38 GMT

>>>>> "TobiasV" == Tobias Verbeke <> >>>>> on Sun, 17 Dec 2006 22:34:50 +0100 writes:

    TobiasV> Martin Maechler wrote:
>> Yes, I think all your propositions would be improvements.
>> OTOH, I don't think the improvements warrant a big
>> increase in code (complexity), nor do I think the
>> improvements are crucial for R's integrity.
>> So... If you (our someone else) provides a patch
>> {against R-devel, as always} which keeps the code simple,
>> I'd strongly consider adding that to R.
    TobiasV> Dear Martin,

    TobiasV> Thank you for the encouragement.

(maybe I shouldn't have done that, see below ...)

    TobiasV> Please find a patch in attachment.  As you will
    TobiasV> see, I also added a warning for models with more
    TobiasV> than 2 parameters.

the latter is a good idea [and I wonder if we should not even signal an error ..]

but for the patch, see below.

    TobiasV> Kind regards, Tobias

       >>>>>>> "Tobias" == Tobias Verbeke
       >>>>>>> <> on Sat, 09 Dec 2006
       >>>>>>> 22:42:38 +0100 writes:
       Tobias> The abline function can be used to draw the
       Tobias> regression line when one passes the lm object as an
       Tobias> argument.
       Tobias> However, if it's an intercept-only model, it appears
       Tobias> to use the intercept as the slope of the abline:
       Tobias> mod <- lm(dist ~ 1, data = cars) 
       Tobias> plot(dist ~ speed, data = cars) 
       Tobias> abline(reg = mod) # nothing appears

       Tobias> This behaves as documented, but might catch
       Tobias> someone. Would it be an improvement if this
       Tobias> situation was detected so as to plot the appropriate
       Tobias> horizontal line, i.e.

       Tobias> abline(a = coef(mod), b = 0) ?

       Tobias> Would it also be an improvement if for a model like

       Tobias> mod2 <- lm(dist ~ 1 + offset(speed), data = cars)

       Tobias> abline(reg = mod2) would be equivalent to

       Tobias> abline(a = coef(mod2), b = 1) ?

       Tobias> For models through the origin, the current function
       Tobias> works fine, but one might even consider models
       Tobias> through the origin and having the independent
       Tobias> variable in an offset() to be fully fool-proof, i.e.

       Tobias> abline(a = 0, b = 1)

       Tobias> Kind regards, Tobias

Comments on your patch:


    <       temp <- as.vector(coef(a))
    <       if(length(temp) == 1) {
    >         tempa <- as.character(terms(a))
    >         coefa <- coef(a)
    >         if (length(coefa) > 2)
    >             warning("The abline function is meant to only plot the regression line for simple linear regression")
    >       if (length(grep("-[[:blank:]]?1", tempa))) {
    <           b <- temp
    >           b <- ifelse(length(grep("offset", tempa)), 1, coefa[1])

yet another misuse of ifelse() .... {as mentioned recently}.
Do note that       if(Cond) A else B   is
quite better than ifelse(Cond, A, B) in these scalar situations.


    <           a <- temp[1]
    <           b <- temp[2]
    >             a <- coefa[1]
    >             if (length(grep("offset", tempa))) b <- 1
    >             else if (length(coefa) >= 2) b <- coefa[2]
    >                  else b <- 0

Hmm, grep()ing in as.character(terms(.)) is not really elegant though we could well live with that if ....

The real problems are
1. your offset dealing cannot work in generality

   {and I should really have *dis*couraged you earlier on this}, since

  1. lm() can have an 'offset' *argument* instead of or in addition to the formula offset() component.
  2. instead of offset(speed) one could have had offset(speed^2) or offset(sqrt(dist)) or "anything".

  Because of the above, it really doesn't make sense trying to   figure out offset corrections, at least not in abline()'s   code, I think.

2. To catch the "horizontal line" situation, it's also not

   sufficient to grep for "-1" (basically); since, e.g.,    "0+" has been available to achieve the same and has actually    been preferred by some.
   OTOH, there is a correct way of asking if there was an    intercept [attr(terms(.), "intercept")],    and I plan to use that in abline.

Martin Maechler, ETH Zurich mailing list Received on Tue Dec 19 03:16:42 2006

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Tue 19 Dec 2006 - 13:30:59 GMT.

Mailing list information is available at Please read the posting guide before posting to the list.