From bbo|ker @end|ng |rom gm@||@com  Mon Sep 23 22:25:46 2024
From: bbo|ker @end|ng |rom gm@||@com (Ben Bolker)
Date: Mon, 23 Sep 2024 16:25:46 -0400
Subject: [Rd] model.matrix() may be misleading for "lme" models
In-Reply-To: <20240923225417.08fef4c1@Tarkus>
References: <a7d44ccb-10b4-4fbb-b34c-154aaa687ef7@mcmaster.ca>
 <b60df077-eab0-451c-a8c5-67e5e333b2da@mcmaster.ca>
 <20240921215156.1c65b61a@trisector>
 <ee50e3bd-364a-4f37-ba03-62aed1df5a8e@mcmaster.ca>
 <20240923225417.08fef4c1@Tarkus>
Message-ID: <CABghstTfAjaU+D-GkN19J6eb-V=6Sc234jEV085PgQR2vTc+qg@mail.gmail.com>

>  I can't tell whether evaluating object$call$data in
environment(object$formula) is a better or worse idea than parent.frame().

I have struggled with this a lot over the years. There is a bunch of
wonky code in lme4, e.g. here
<https://github.com/lme4/lme4/blob/master/R/lmer.R#L814-L838>, that
tries to look for data in different possible locations, but I don't
think anything works perfectly/robustly.

https://stackoverflow.com/questions/14945274/determine-whether-evaluation-of-an-argument-will-fail-due-to-non-existence

On Mon, Sep 23, 2024 at 3:54?PM Ivan Krylov via R-devel
<r-devel at r-project.org> wrote:
>
> ? Sun, 22 Sep 2024 10:23:50 -0400
> John Fox <jfox at mcmaster.ca> ?????:
>
> > > 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()?
>
> Yes, I do mean the parent frame of the model.matrix.lme() function
> call. While eval()'s default for the 'envir' argument is
> parent.frame(), this default value is evaluated in the context of the
> eval() call. Letting model.matrix.lme() call eval() results in the
> 'envir' being the eval()'s parent, the model.matrix.lme() call frame.
>
> In most cases, model.matrix.lme() works as intended: either lme() has
> been given the 'data' argument, so object$data is not NULL and the
> branch to eval() is not taken, or 'data' has not been given, so both
> object$data and object$call$data are NULL, and NULL doesn't cause any
> harm when evaluated in any environment. In the latter case
> model.matrix.default() can access the variables in the environment of
> the formula.
>
> With keep.data = FALSE, the function may evaluate object$call$data in
> the wrong environment:
>
> maybe_model_matrix <- function(X)
>  model.matrix(lme(distance ~ Sex, random = ~ 1 | Subject, X,
>                   contrasts=list(Sex=contr.sum), keep.data=FALSE))
>
> maybe_model_matrix(Orthodont)
> # Error in eval(object$call$data) : object 'X' not found
>
> ...but then model.matrix.default doesn't work on such objects either,
> and if the user wanted the data to be accessible, they could have set
> keep.data = TRUE. I can't tell whether evaluating object$call$data in
> environment(object$formula) is a better or worse idea than
> parent.frame().
>
> --
> Best regards,
> Ivan
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] model.matrix() may be misleading for "lme" models
Ben Bolker