Dear Prof. John Fox, ? Sat, 21 Sep 2024 12:47:49 -0400 John Fox <jfox at mcmaster.ca> ?????:> NextMethod(formula(object), data=eval(object$call$data), > contrasts.arg=object$contrasts)The use of NextMethod worries me a bit. It will work as intended as long as everyone gives fully-named arguments to the generic, without relying on positional or partial matching, but may give unexpected results otherwise: foo <- \(x, ...) UseMethod('foo') foo.default <- \(x, foo = 'default', baz = 'baz', ...) list(foo = foo, baz = baz, '...' = list(...)) # try to override the argument to the default method foo.bar <- \(x, ...) NextMethod(x, foo = 'override') x <- structure(list(), class = 'bar') foo(x) # works, gives the right argument to foo.default # $foo # [1] "override" # # $baz # [1] "baz" # # $... # list() # this used to work with foo.default, but now doesn't: foo(x, fo = 'bar') # not matched to foo# $foo # [1] "override" # # $baz # [1] "baz" # # $... # $...$fo # [1] "bar" foo(x, 'bar') # not matched to foo=, given to baz# $foo # [1] "override" # # $baz # [1] "bar" # # $... # list() This happens because NextMethod() overwrites named arguments already present in the call, but any other arguments just get appended, without any regard to whether they had already matched an argument before the call was modified. In fact, I'm not seeing a way to safely override some of the arguments for the next S3 method. The "attempt 4" described by Henrik Bengtsson at [1] seems to work only if an argument is given as part of the call: foo.bar <- \(x, foo, ...) { foo <- 'override'; NextMethod() } foo(x) # doesn't work # $foo # [1] "default" # # $baz # [1] "baz" # # $... # list() foo(x, 1) # does work # $foo # [1] "override" # # $baz # [1] "baz" # # $... # list() Evaluating object$call$data in the environment of the suggested nlme:::model.matrix.lme function may also not work right. Without an explicit copy of the data, the best environment to evaluate it in would be parent.frame(). -- Best regards, Ivan [1] https://github.com/HenrikBengtsson/Wishlist-for-R/issues/44
Dear Ivan, Thank you for addressing my questions with your usual thoroughness. Please see below: On 2024-09-21 2:51 p.m., Ivan Krylov wrote:> [You don't often get email from ikrylov at disroot.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] > > Caution: External email. > > > Dear Prof. John Fox, > > ? Sat, 21 Sep 2024 12:47:49 -0400 > John Fox <jfox at mcmaster.ca> ?????: > >> NextMethod(formula(object), data=eval(object$call$data), >> contrasts.arg=object$contrasts) > > The use of NextMethod worries me a bit. It will work as intended as > long as everyone gives fully-named arguments to the generic, without > relying on positional or partial matching, but may give unexpected > results otherwise:That's not an issue for car:::model.matrix.lme(), which isn't registered and so isn't accessible to users, but could be a problem if model.matrix.lme() is incorporated in the nlme package, as I suggested. An alternative that I think should work would be to call model.matrix(formula(object), data=eval(object$call$data), contrasts.arg=object$contrasts, ...) rather than NextMethod() from model.matrix.lme(). . . .> Evaluating object$call$data in the environment of the suggested > nlme:::model.matrix.lme function may also not work right. Without an > explicit copy of the data, the best environment to evaluate it in would > be parent.frame().I'm afraid that I don't understand the suggestion. Isn't parent.frame() the default for the envir argument of eval()? Do you mean the parent frame of the call to model.matrix.lme()? I tested car:::Anova.lme()/model.matrix.lme() with models fit to data in the global environment, in an attach()ed data frame, and within another function(), and didn't encounter any problems. For example: ------ snip ----- > f <- function(){ + OD <- Orthodont + m7 <- with(OD, lme(distance ~ Sex, random = ~ 1 | Subject, + contrasts=list(Sex=contr.sum))) + Anova(m7, type=3) + } > f() Analysis of Deviance Table (Type III tests) Response: distance Chisq Df Pr(>Chisq) (Intercept) 3910.8377 1 < 2.2e-16 Sex 9.2921 1 0.002301 ------ snip ----- Best, John> > -- > Best regards, > Ivan > > [1] https://github.com/HenrikBengtsson/Wishlist-for-R/issues/44