Søren Højsgaard
2012-Sep-17 22:26 UTC
[R] "eval" inside a function call in connection with updating the data slot in the call of lmer
Dear list, Given a linear mixed model (from lme4) I want to 1) first change the input dataset and then 2) change the model formula. I want this to happen in a function call; Please see below. Options 1) and 2) below work whereas 3) fails with the message> foo()Error in is.data.frame(data) : object 'beets2' not found Question: What is it one must to in case 3) to have R look "inside" the function to figure out what "beets2" is? Best regards S?ren ________________ library(pbkrtest) data(beets) lgs <- lmer(sugpct~block+sow+harvest+(1|block:harvest), data=beets, REML=F) foo <- function(){ ## 1) beets2 <- transform(beets, yy = sugpct * yield) ma1 <- lmer(yy~block+sow+harvest+(1|block:harvest), data=beets2, REML=F) ma0 <- update(ma1, yy~.) ## 2) cl <- getCall(lgs) cl[["data"]] <- beets2 mb1 <- eval(cl) mb0 <- update(mb1, yy~.) mb0 ## 3) cl <- getCall(lgs) cl[["data"]] <- as.name("beets2") mc1 <- eval(cl) mc0 <- update(mc1, yy~.) mc0 } foo()
David Winsemius
2012-Sep-17 22:55 UTC
[R] "eval" inside a function call in connection with updating the data slot in the call of lmer
On Sep 17, 2012, at 3:26 PM, S?ren H?jsgaard wrote:> Dear list, > Given a linear mixed model (from lme4) I want to 1) first change the input dataset and then 2) change the model formula. I want this to happen in a function call; > Please see below. Options 1) and 2) below work whereas 3) fails with the message >> foo() > Error in is.data.frame(data) : object 'beets2' not found > > Question: What is it one must to in case 3) to have R look "inside" the function to figure out what "beets2" is?That will depend on how you offer that 6 letter sequence to the interpreter. Surrounded by quotes will be quite different than without quotes> > Best regards > S?ren > ________________ > > library(pbkrtest) > data(beets) > lgs <- lmer(sugpct~block+sow+harvest+(1|block:harvest), data=beets, REML=F) > > foo <- function(){ > ## 1) > beets2 <- transform(beets, yy = sugpct * yield) > ma1 <- lmer(yy~block+sow+harvest+(1|block:harvest), data=beets2, REML=F) > ma0 <- update(ma1, yy~.) > ## 2) > cl <- getCall(lgs) > cl[["data"]] <- beets2 > mb1 <- eval(cl) > mb0 <- update(mb1, yy~.) > mb0 > ## 3) > cl <- getCall(lgs) > cl[["data"]] <- as.name("beets2")The problem here is that 'beets2' is just a character vector ... with no binding. I'm wondering if you instead want: cl[["data"]] <- get("beets2")> mc1 <- eval(cl) > mc0 <- update(mc1, yy~.) > mc0 > } > foo()No guarantees. I'm not a particularly experienced surgeon of lmer-objects.>-- David Winsemius, MD Alameda, CA, USA
Duncan Murdoch
2012-Sep-17 23:47 UTC
[R] "eval" inside a function call in connection with updating the data slot in the call of lmer
On 12-09-17 6:26 PM, S?ren H?jsgaard wrote:> Dear list, > Given a linear mixed model (from lme4) I want to 1) first change the input dataset and then 2) change the model formula. I want this to happen in a function call; > Please see below. Options 1) and 2) below work whereas 3) fails with the messageI get the failure in 1), not in 3). I think it's a bug. The problem appears to be that the update method for mer objects looks in the wrong place for its variables. It is looking in parent.frame() (i.e. in the caller), but the caller isn't you. The method should be looking in parent.frame(2). You can fix this yourself if you have the lme4 source (it's line 1483 of lmer.R in version 0.999999-0) but you probably want to send your sample code to the maintainers. Making that change might break something else. Duncan Murdoch>> foo() > Error in is.data.frame(data) : object 'beets2' not found > > Question: What is it one must to in case 3) to have R look "inside" the function to figure out what "beets2" is? > > Best regards > S?ren > ________________ > > library(pbkrtest) > data(beets) > lgs <- lmer(sugpct~block+sow+harvest+(1|block:harvest), data=beets, REML=F) > > foo <- function(){ > ## 1) > beets2 <- transform(beets, yy = sugpct * yield) > ma1 <- lmer(yy~block+sow+harvest+(1|block:harvest), data=beets2, REML=F) > ma0 <- update(ma1, yy~.) > ## 2) > cl <- getCall(lgs) > cl[["data"]] <- beets2 > mb1 <- eval(cl) > mb0 <- update(mb1, yy~.) > mb0 > ## 3) > cl <- getCall(lgs) > cl[["data"]] <- as.name("beets2") > mc1 <- eval(cl) > mc0 <- update(mc1, yy~.) > mc0 > } > foo() > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >