How can I define environments within a function so that they are visible
to calls to a sub-function?
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
--
Giles Hooker
Assistant Professor:
Department of Biological Statistics and Computational Biology
Department of Statistical Science
1186 Comstock Hall
Cornell University
Ithaca, NY, 14853
Ph: (+1 607) 255 1638
Fax: (+1 607) 255 4698
Email: giles.hooker at cornell.edu
--
Giles Hooker
Assistant Professor:
Department of Biological Statistics and Computational Biology
Department of Statistical Science
1186 Comstock Hall
Cornell University
Ithaca, NY, 14853
Ph: (+1 607) 255 1638
Fax: (+1 607) 255 4698
Email: giles.hooker at cornell.edu
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 > > >
Matt Calder wrote:> Duncan, > > Sorry to be, well, nit picking, but I can't get your example to run. I > am a longtime Splus user and am only using R on the side. The concept of > environments is one I have yet to grasp. I think the example you are trying > to provide will illuminate things for me, but it doesn't source. The > definition of fnBuilder sources fine, though I am not sure what the > "commonArgs <- ..." is meant to do. Anyway, calling: >That wasn't R code, it was pseudocode. That's why I asked the original poster for a real example: pseudocode examples aren't useful. But I shouldn't have posted one myself, I should just have stopped at the first paragraph. Duncan Murdoch> >> both <- fnBuilder(...) >> > Error: '...' used in an incorrect context > > and so I though, maybe you meant: > > >> both <- fnBuilder(c(1,2,3)) >> > Error in fnBuilder(c(1, 2, 3)) : '...' used in an incorrect context > > But then I thought you were perhaps using "..." as a placeholder not as > syntax and so I have little idea what it is you are trying to show. Could > you clarify what your example is demonstrating in regards to scoping? > > So far, I have found the only part of R my Splus knowledge doesn't > translate is in regard to this sort of thing. I can't tell you how much pain > translating "substitute" idioms into R has caused me. Thanks, > > Matt > > > > > ----- Original Message ----- > From: "Duncan Murdoch" <murdoch at stats.uwo.ca> > To: <gjh27 at cornell.edu> > Cc: <r-devel at r-project.org> > Sent: Thursday, August 28, 2008 5:42 AM > Subject: Re: [Rd] Defining environments within functions > > > >> 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 >>> >>> >>> >>> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > >