bernddude
bernddude

Reputation: 31

Closure and lm in R

Hi i tried to prepare a little demo code for closures in R when i stumbled into some odd behavior. From using Debug i realize that the failure happens due to the fact that inside of lm this line is being executed

mf <- eval(mf, parent.frame())

however it seems to defeat the functional aspect of programming with closures ?

what am i missing ? here is my little example

# typical closure use 
foo <- function(formula,data,weight=NULL) {
  if(is.null(weight)) w=ones(nrow(data),1) else w=weight    
  force(w)  
  lm(formula,data,weights=w)
}

setup_something <- function(...) {
   function(formula,data) {
     foo(formula,data,...)
   }
}

# set up our model function
model <- setup_something()

# set up our data 
df = data.frame(x=seq(1,10,1),y=c(1:10)^1.5 * 3 + 2)
model(y~x,df)

Error in eval(expr, envir, enclos) : object 'w' not found

Upvotes: 2

Views: 199

Answers (1)

Jthorpe
Jthorpe

Reputation: 10167

Instantiating a formula (i.e.x~y) captures both the environment it is created in, which in your cases happens in the parent.frame() of your call to model().

If you want to subjugate the environment, you can do so explicitly by adding this line right before your call to lm(formula,data,weights=w):

# explicitly replace the formula's environment with the current frame
attr(formula,'.Environment')  <-  sys.frame(sys.nframe())

or implicitly by by replacing your call to lm(formula,data,weights=w) with:

#instantiate a new forumla based on the existing formula
lm(stats::formula(unclass(formula)),data,weights=w)

By way of background, if you were to stick the following line into lm() right before the call to mf <- eval(mf, parent.frame()):

print(ls(envir=parent.frame()))

you would get a list of object names that includes "w". However, the 'mf' object being evaluated is a stats::model.frame thanks to this line:

mf[[1L]] <- quote(stats::model.frame)

and stats::model.frame evaluates the arguments to mf in the context of the .Environment attribute of the formula.

Upvotes: 1

Related Questions