I am trying to build a function in a context where the environment concept would appear to be useful. But I'm a bit foggy about this concept and would appreciate some pointers and advice. Basically the function I'm building, say foo(x,t), is a function of two variables). Depending on the value of t, foo will return one of the values f1(x), f2(x), ..., fk(x), where each of f1, ..., fk is a piecewise linear function (built using approxfun()). Now I want other functions to be able to get at these pwl functions, making use of a syntax of the form bar(y,foo) so that in the code of bar() I could have assignments like clyde <- get("f1",envir=environment(foo)) So rather than assigning f1, ..., fk in the body of foo, I would like to assign them in the environment of foo. I want to do something like environment(foo) <- melvin where melvin contains f1, ..., fk. But how do I create ``melvin'' so that it is acceptable to the foregoing assignment? One way I ***could*** go about it would be to create melvin as a list: melvin <- list(f1=f1,f2=f2,etc.) Then I could do attach(melvin) environment(foo) <- as.environment(2) This seems to work ... but it also seems unnecessarily convoluted. I could also do assign("f1",f1,envir=environment(foo)) assign("f2",f2,envir=environment(foo)) etc. after creating foo(), but this is tejous. I think I must be missing a point or three. As I said, I don't really grok environments. Given that what I want to do makes any kind of sense at all, can someone start me off in the right direction? cheers, Rolf Turner rolf at math.unb.ca
On 4/13/2006 11:38 AM, Rolf Turner wrote:> I am trying to build a function in a context where the environment > concept would appear to be useful. But I'm a bit foggy about this > concept and would appreciate some pointers and advice. > > Basically the function I'm building, say foo(x,t), is a function of > two variables). Depending on the value of t, foo will return one of > the values f1(x), f2(x), ..., fk(x), where each of f1, ..., fk is a > piecewise linear function (built using approxfun()). > > Now I want other functions to be able to get at these pwl functions, > making use of a syntax of the form > > bar(y,foo) > > so that in the code of bar() I could have assignments like > > clyde <- get("f1",envir=environment(foo)) > > So rather than assigning f1, ..., fk in the body of foo, I would like > to assign them in the environment of foo. > > I want to do something like > > environment(foo) <- melvin > > where melvin contains f1, ..., fk. But how do I create ``melvin'' > so that it is acceptable to the foregoing assignment?Generally it's not necessary to explicitly set the environment. Here the way to get what you want is to define f1 and foo in the same environment; then environment(foo) (which defaults to the environment where it was created) will contain f1. So you can have a function like this: makefoo <- function() { f1 <- ... f2 <- ... foo <- ... return(foo) } and the environment of the call to makefoo() will live as long as foo does.> > One way I ***could*** go about it would be to create melvin > as a list: > > melvin <- list(f1=f1,f2=f2,etc.) > > Then I could do > > attach(melvin) > environment(foo) <- as.environment(2) > > This seems to work ... but it also seems unnecessarily convoluted. > > I could also do > > assign("f1",f1,envir=environment(foo)) > assign("f2",f2,envir=environment(foo)) > etc. > > after creating foo(), but this is tejous. I think I must be missing > a point or three. As I said, I don't really grok environments.This is probably a bad idea, since the environment of foo (as you originally set it up) was likely .GlobalEnv. So this would be equivalent to just having code f1 <- ... f2 <- ... foo <- ... and so on.> Given that what I want to do makes any kind of sense at all, can > someone start me off in the right direction.Maybe this helped? Duncan Murdoch
Brian Ripley wrote:> Can I also suggest local()? This does a similar thing in a perhaps > more natural way.Sorry, I'm not with you. I'm slow, and as I said, I don't really grok environments. Let's look at a toy example. Suppose I want to create a function foo: function(x){x^n} and assign n the value of 4, say, in the environment of foo. Duncan Murdoch's solution was to create a function make.foo: make.foo <- function() { n <- 4 foo <- function(x){x^n} foo } and then execute foo <- make.foo() How would I go about accompishing the same (toy) task making use of the local() function? Thanks. cheers, Rolf
Thomas Lumley wrote:> foo <- local({ > n <- 4 > function(x) {x^n} > })Bewdy! Thanks a lot. Slowly but slowly ( :-) ) I learn things! cheers, Rolf
If you think of n and the function as components of an object then you could use the proto package to define an object, p, that contains those two components. If we assume no children of p are required (from your description I assume that that is the case) then its just: library(proto) p <- proto(n = 4, f = function(., x) x^n) p$f(2) # 16 # we can later change the value of n p$n <- 3 p$f(2) # 8 On 4/13/06, Rolf Turner <rolf at math.unb.ca> wrote:> Thomas Lumley wrote: > > > foo <- local({ > > n <- 4 > > function(x) {x^n} > > }) > > Bewdy! Thanks a lot. Slowly but slowly ( :-) ) I learn things! > > cheers, > > Rolf > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html >