R uses lexical scoping, not dynamic scoping. It does not matter where
bar is called from. What matters is where bar was defined and since
bar was defined in the global environment that is where its free
variables are looked up thus environment(bar) is the global
environment. Try changing foo to this which creates a new function,
also called bar, which only exists for the duration of the call to foo
and its free variables are looked up within foo. We assign the
variables within foo and then call this newly created bar.
foo <- function(x,zeta) {
environment(bar) <- environment()
for(nm in names(zeta)) assign(nm,zeta[nm])
bar(x)
}
If we regard bar as a method acting on an object whose variables are
alpha, beta and gamma then we can use the proto package like this:
library(proto) # see http://r-proto.googlecode.com
p <- proto(alpha = 2, beta = 3, gamma = -4,
bar = function(this, x) this$alpha + this$beta * exp(this$gamma + x))
p$bar(0.1)
# we could change any of the variables and run again
# e.g. p$alpha <- 3; p$bar(0.1)
# or we could create a child of p, q.
# q inherits all of p's variables and methods
# however, let's explicitly override alpha
q <- p$proto(alpha = 12)
q$bar(0.1)
On Wed, Dec 9, 2009 at 10:43 PM, Rolf Turner <r.turner at auckland.ac.nz>
wrote:>
> I am working with a somewhat complicated structure in which
> I need to deal with a function that takes ``basic'' arguments
> and also depends on a number of parameters which change depending
> on circumstances.
>
> I thought that a sexy way of dealing with this would be to assign
> the parameters as objects in the environment of the function in
> question.
>
> The following toy example gives a bit of the flavour of what I
> am trying to do:
>
> foo <- function(x,zeta) {
> for(nm in names(zeta)) assign(nm,zeta[nm],envir=environment(bar))
> bar(x)
> }
>
> bar <- function(x) {
> alpha + beta*exp(gamma*x)
> }
>
> v <- c(alpha=2,beta=3,gamma=-4)
>
> ls()
> [1] "bar" "foo" "v"
>
> foo(0.1,v)
> ?alpha
> 4.01096
>
> 2+3*exp(-4*0.1)
> [1] 4.01096 ? ? ?# Check; yes it's working; but ...
>
> ls()
> [1] "alpha" "bar" ? "beta" ?"foo" ?
"gamma" "v"
>
> The parameters got assigned in the global environment (as well as in
> the environment of bar()? Or instead of?).
>
> I didn't want that to happen.
>
> Questions:
>
> (a) What did I do wrong?
> (b) What am I not understanding about environments?
> (c) How can I get the parameters to be assigned in the environment of bar()
> ? ?and ***NOT*** in the global environment?
> (d) Is it time to go to the pub yet?
>
> [Please don't make suggestions about doing it all some other way, e.g.
> using the ``...'' argument facility. ?I know there are other ways
to
> attack my problem (but they may not be so efficacious in the context
> of my real --- as opposed to toy --- example). ?I want to try to get
> the environment idea to work, and I want to understand more about
> environments and how they work.]
>
> Thanks for any insights.
>
> ? ? ? ?cheers,
>
> ? ? ? ? ? ? ? ?Rolf Turner
>
> P. S. Are there any articles about environments (in the sense used above)
> out there in the literature? ?I searched the contents of the R Journal/R
> News
> but turned up nothing on environments.
>
> ? ? ? ? ? ? ? ?R. T.
>
> ######################################################################
> Attention:\ This e-mail message is privileged and confid...{{dropped:9}}
>
> ______________________________________________
> 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.
>