[R] working with eval and environments

Duncan Murdoch murdoch.duncan at gmail.com
Mon Sep 20 12:46:11 CEST 2010


darckeen wrote:
> I'm trying to get the following section of code to work, I think the problem
> is being caused by the assignment of data to the lm function not evaluating
> to "train" in the parent environment but I can't seem to figure out how to
> do this.
>   

I'd suggest simplifying this.  Packing things into S4 objects probably 
doesn't have any relevance, but it makes the code harder to understand.  
Similarly,

as.formula("y ~ 1")

could be simplified to just

y ~ 1

and then it would be clear what it does.  (It declares that y is a 
variable in the current environment.  I suspect as.formula does the 
same, but I'd have to check.)

And the do.call() calls don't seem necessary for a scoping question 
(though they might be necessary in your application, I don't know.)

Duncan Murdoch

> fitmodel <- function(trial,data)
> {	
> 	wrap.lm <- function(formula,data,...) { cat("in wrap lm",NROW(data),"\n");
> lm(formula,data,...) }
> 	wrap.step <- function(object,scope,...) { cat("in wrap
> step",NROW(train),"\n"); step(object,scope,...) }
> 	
> 	train <- data[1:trial at n,]
> 	null <- as.formula("y ~ 1")
> 	full <- as.formula("y ~ 1 + x1 + x2")
> 	
> 	cat("in fit",NROW(train),"\n")
> 	model <- do.call(trial at fit$func,trial at fit$args)
> 	print(model$call)
> 	select <- do.call(trial at step$func,trial at step$args)
> }
>
> mydf <- data.frame(y <- runif(100),x1 <- runif(100),x2 <- runif(100))
> myfit <- list(func="wrap.lm",args=alist(formula=null,data=train))
> mystep <- list(func="wrap.step",args=alist(object=model,scope=full,trace=0))
>
> setClass("trial",representation(n="numeric",fit="list",step="list"))
> trial1 <- new("trial",n=50,fit=myfit,step=mystep)
> trial2 <- new("trial",n=75,fit=myfit,step=mystep)
>
> result <- lapply(list(trial1,trial2),fitmodel,mydf)
> print(coef(result[[1]]))
> print(coef(result[[2]]))
> cat("result #1",NROW(result[[1]]$model),"\n")
> cat("result #2",NROW(result[[2]]$model),"\n")
>
>
> The resulting output is:
> in fit 50 
> in wrap lm 50 
> lm(formula = formula, data = data)
> in wrap step 50 
> in fit 75 
> in wrap lm 75 
> lm(formula = formula, data = data)
> in wrap step 75 
> (Intercept) 
>   0.5276266 
> (Intercept) 
>   0.5276266 
> result #1 100 
> result #2 100 
>
> I think what is happening is that step is reassigning the "data" for lm to
> the fitmodel environment thus using resulting in using 100 rows.  Any ideas
> would be appreciated.
>



More information about the R-help mailing list