R-beta: update.{glm,lm}

Thomas Lumley (thomas@biostat.washington.edu)
Mon, 28 Apr 1997 10:35:44 -0700 (PDT)


Date: Mon, 28 Apr 1997 10:35:44 -0700 (PDT)
From: Thomas Lumley <thomas@biostat.washington.edu>
To: R-help@stat.math.ethz.ch
Subject: R-beta: update.{glm,lm}
In-Reply-To: <Pine.SUN.3.95.970428075618.1365B-100000@zen>

Three bugs and 2.5 fixes.

1. To make update() work with a new formula for glms, change the first
line of the glm() function from
call <- sys.call(
to
call<-match.call()
(this means that the formula component of the returned call is labelled so
that update can find it)

2. update.lm doesn't do anything with its weights= argument
Add
	if (!missing(weights))
		call$weights<-substitute(weights)

Similarly, to get update to work properly on glms you need a lot more of
these if statements (see update.glm at the end of the message).

3. update.lm evaluates its arguments in the wrong frame. It creates a
modified version of the original call and evaluates it in 
sys.frame(sys.parent()).  If update.lm is called directly this is correct,
but if it is called via update() the correct frame is
sys.frame(sys.parent(2)). Worse still, if it is called by NextMethod()
from another update.foo() the correct frame is still higher up the list.

My solution (a bit ugly) is to move up the list of enclosing calls
checking at each stage to see if the call is NextMethod, update or an
update method.  It can be seen at the end of update.glm at the bottom of
this message, and something of this sort needs to be added to other update
methods.


Thomas Lumley
------------------------------------------------------+------
Biostatistics		: "Never attribute to malice what  :
Uni of Washington	:  can be adequately explained by  :
Box 357232		:  incompetence" - Hanlon's Razor  :
Seattle WA 98195-7232	:				   :
------------------------------------------------------------

update.glm<-function (glm.obj, formula, data, weights, subset, na.action, 
        offset, family, x) 
{
        call <- glm.obj$call
        if (!missing(formula)) 
                call$formula <- update.formula(call$formula, 
                        formula)
        if (!missing(data)) 
                call$data <- substitute(data)
        if (!missing(subset)) 
                call$subset <- substitute(subset)
        if (!missing(na.action)) 
                call$na.action <- substitute(na.action)
        if (!missing(weights)) 
                call$weights <- substitute(weights)
        if (!missing(offset)) 
                call$offset <- substitute(offset)
        if (!missing(family)) 
                call$family <- substitute(family)
        if (!missing(x)) 
                call$x <- substitute(x)
        notparent <- c("NextMethod", "update", methods(update))
        for (i in 1:(1+sys.parent())) {
                parent <- sys.call(-i)[[1]]
                if (is.null(parent))
			break	
		if (is.na(match(as.character(parent), notparent)))
                        break
        }	
        eval(call, sys.frame(-i))
}

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request@stat.math.ethz.ch
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=