[R] Summary: do.call and environments
Simon Fear
Simon.Fear at synequanon.com
Fri Mar 12 10:43:27 CET 2004
It is possible to fake something very like dynamic scoping
in S-PLUS as in the following example:
fx <- function(y) print(get("x", inherit=T) * y)
fxx <- function(fun,x) fun(3)
fxx(fx,2)
[1] 6
As several posters already pointed out; this strategy will
not always do what you want (it will pick up the first x defined in
the frames stack, rather than necessarily the x passed to fxx,
in a more complicated nested call) - that's the downside of
dynamic scoping.
In R the above will not do what you want at all; fx will still be
evaluated in the environment in which it was defined, and will
never read the x passed to fxx.
You COULD do this in R:
fx <- function(y) print(get("x", envir=sys.parent()) * y)
but that will only work for fx called from fxx directly - you cannot
set both envir and inherits arguments in R (nor both frame and
inherit in S-PLUS).
But in R you can do (thanks Tony, mod Gabor)
fx <- function(y) print(x*y)
fxx <- function(fun, x) {
environment(fun) <- environment()
fun(3)
}
And that's a lovely example of the power of lexical scoping,
guaranteeing that the x of the fxx call will be used. [Provided
you don't reset the environment again before calling fun, but
why would you ever do that?]
Incidentally, anyone for golf? How about
fxx <- function(fun,x) eval(parse(text=deparse(fun)))(3)
The above won't work in S-PLUS by the way, not even if you
force the eval in sys.parent(). That's the kind of thing that used
to drive me mad in S-PLUS - why, oh why, doesn't it work? [Don't
answer that.]
IMHO there isn't going to be a solution that works in both R and
S-PLUS - now there's asking to be shot down in flames - or if there is,
it would not be natural to either dialect. Scoping is precisely where
R and S-PLUS do not match.
Having said that I wonder if the original poster really needed to
get into this problem at all, what is wrong with
fxy <- function(x,y) print(x*y)
ffxy <- function(fun,x,y) fun(x,y)
ffxy(fxy,2,3)
IE just pass x as an argument. That works in all S.
HTH
Simon
Simon Fear
Senior Statistician
Syne qua non Ltd
Tel: +44 (0) 1379 644449
Fax: +44 (0) 1379 644445
email: Simon.Fear at synequanon.com
web: http://www.synequanon.com
Number of attachments included with this message: 0
This message (and any associated files) is confidential and\...{{dropped}}
More information about the R-help
mailing list