From murdoch at stats.uwo.ca  Thu Aug 28 12:42:54 2008
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Thu, 28 Aug 2008 06:42:54 -0400
Subject: [Rd] Defining environments within functions
In-Reply-To: <48B60482.5010306@cornell.edu>
References: <48B60482.5010306@cornell.edu>
Message-ID: <48B6812E.70809@stats.uwo.ca>

Giles Hooker wrote:
> How can I define environments within a function so that they are visible
> to calls to a sub-function?
>   

I think you need to give a simplified, runnable example.  (Or at least 
runnable until it hits the scoping problem you've got.)  "Sub-function" 
isn't R terminology, and it's not clear what you mean by it.

In R, you rarely need to work with environments explicitly.  You just 
define functions in the same location and they share the same 
environment.  For example,

fnBuilder <- function(commonArgs) {
  commonVars <- ...
  ProfileErr <- function(params, ...) {}
  coefs <- function(params, ...) {}
  return(list(ProfileErr, coefs))
}

both <- fnBuilder(...)
ProfileErr <- both[[1]]
coefs <- both[[2]]

Now ProfileErr and coefs share the same environment, and both can see 
(and modify) commonArgs and commonVars.

Duncan Murdoch


> I have defined an objective function,
>
> 	ProfileErr = function(params,...)
>
> which I would like to optimize using standard routines (optim,
> nlminb,....) but which contains auxiliary variables which need to be
> updated along with params. No optimization routine in R that I have
> found has facilities for this.
>
> Specifically, within ProfileErr, I need to calculate
>
>   	coefs(params,...)
>
> This a function which requires a further optimization, and I can achieve
> significant efficiency gains by starting  where the last optimization
> ended, so I would like to keep track of it.
>
> At the command line, I get around this by
>
> 	ProfileEnv = new.env()
> 	assign('coefs',coefs,3,ProfileEnv)
>
> and within ProfileErr, I can call
>
> 	startcoefs = get('coefs',envir=ProfileEnv)
> 	* do the optimization to get newcoefs *
> 	assign('coefs',newcoefs,3,ProfileEnv)
>
> Then calling
>
> 	optim(pars,ProfileErr,....)
>
> works fine. However, when I try to wrap all of that in its own function
>
> 	profile.estimate = fn(pars,...){
> 		ProfileEnv = new.env()
> 		assign('coefs',coefs,3,ProfileEnv)
> 	
> 		res = optim(pars,ProfileErr,....)
> 	}
>
>
> ProfileErr no longer sees ProfileEnv. I haven't been able to make much
> sense out of the documentation on environments, but is there a way to
> make this work? Otherwise I'm back to writing variables out to files.
>
> Many thanks,
>
> Giles
>
>
>



[Rd] Defining environments within functions
Duncan Murdoch