Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
fcn(2)
# Error in fcn(2) : attempt to apply non-function
Apparently, I do not understand enough here. Please, enlighten me. In
the meantime I stick with foo2().
Best,
Henrik
Return function from function with minimal environment
10 messages · Thomas Lumley, Roger D. Peng, Brian Ripley +3 more
On Tue, 4 Apr 2006, Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
I don't think you want to remove baseenv() from the environment. If you
do, no functions from baseenv will be visible inside fcn. These include
"{" and "*", which are necessary for your function. I think the error
message comes from being unable to find "{".
Also, there is no memory use from having baseenv in the environment, since
all the objects in baseenv are always present.
-thomas
Thomas Lumley Assoc. Professor, Biostatistics
tlumley at u.washington.edu University of Washington, Seattle
In R 2.3.0-to-be, I think you can do
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { scale * x }
environment(g) <- emptyenv()
g
}
-roger
Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
fcn(2)
# Error in fcn(2) : attempt to apply non-function
Apparently, I do not understand enough here. Please, enlighten me. In
the meantime I stick with foo2().
Best,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/
On Tue, 4 Apr 2006, Roger D. Peng wrote:
In R 2.3.0-to-be, I think you can do
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { scale * x }
environment(g) <- emptyenv()
g
}
You can, but you really don't want to and you will get the same error. A
'minimal environment' is baseenv(), since you are not going to be able to
do very much without the primitives such as * (and even "{"), and
(relevant here) you will never save anything from it so it will cost you
nothing. In this example, 'scale' is supposed to being picked up from the
environment. So (removing all the empty statements to save memory)
foo <- function(huge) {
scale <- mean(huge)
env <- new.env(parent=baseenv())
assign("scale", scale, envir=env)
bar <- function(x) { scale * x }
environment(bar) <- env
bar
}
is I think minimal baggage (and fcn saves in 153 bytes).
-roger Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
fcn(2)
# Error in fcn(2) : attempt to apply non-function
Apparently, I do not understand enough here. Please, enlighten me. In
the meantime I stick with foo2().
Best,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
On 4/4/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
On Tue, 4 Apr 2006, Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
I don't think you want to remove baseenv() from the environment. If you
do, no functions from baseenv will be visible inside fcn. These include
"{" and "*", which are necessary for your function. I think the error
message comes from being unable to find "{".
Thank you, this makes sense. Modifying Roger Peng's example
illustrates what you say:
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) x
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# [1] 2
But as soon as you add "something" to the g(), it is missing;
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { x }
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# Error in fcn(2) : attempt to apply non-function
...and I did not know that "{" and "(" are primitive functions. Interesting.
I conclude that 'env <- new.env(parent=baseenv())' is better than
''env <- new.env()' in my case.
I learned something new. Thanks.
Henrik
Also, there is no memory use from having baseenv in the environment, since
all the objects in baseenv are always present.
-thomas
Thomas Lumley Assoc. Professor, Biostatistics
tlumley at u.washington.edu University of Washington, Seattle
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
-- Henrik Bengtsson Mobile: +46 708 909208 (+2h UTC)
On 4/4/06, Henrik Bengtsson <hb at maths.lth.se> wrote:
On 4/4/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
On Tue, 4 Apr 2006, Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
I don't think you want to remove baseenv() from the environment. If you
do, no functions from baseenv will be visible inside fcn. These include
"{" and "*", which are necessary for your function. I think the error
message comes from being unable to find "{".
Thank you, this makes sense. Modifying Roger Peng's example
illustrates what you say:
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) x
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# [1] 2
But as soon as you add "something" to the g(), it is missing;
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { x }
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# Error in fcn(2) : attempt to apply non-function
...and I did not know that "{" and "(" are primitive functions. Interesting.
I conclude that 'env <- new.env(parent=baseenv())' is better than
''env <- new.env()' in my case.
Is there any reason to use env <- new.env(parent=baseenv()) instead of just env <- baseenv() ? The extra environment being created seems to serve no purpose.
"Roger" == Roger D Peng <rpeng at jhsph.edu>
on Tue, 04 Apr 2006 10:38:29 -0400 writes:
Roger> In R 2.3.0-to-be, I think you can do
Roger> foo <- function(huge) {
Roger> scale <- mean(huge)
Roger> g <- function(x) { scale * x }
Roger> environment(g) <- emptyenv()
Roger> g
Roger> }
yes, but for now, and for the given purpose,
also as seen in examples, such as splinefun() or approxfun(),
just rm() the things you don't want in the environment.
I.e.,
foo <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
Martin
Roger> -roger
Roger> Henrik Bengtsson wrote:
>> Hi,
>>
>> this relates to the question "How to set a former environment?" asked
>> yesterday. What is the best way to to return a function with a
>> minimal environment from a function? Here is a dummy example:
>>
>> foo <- function(huge) {
>> scale <- mean(huge)
>> function(x) { scale * x }
>> }
>>
>> fcn <- foo(1:10e5)
>>
>> The problem with this approach is that the environment of 'fcn' does
>> not only hold 'scale' but also the memory consuming object 'huge',
>> i.e.
>>
>> env <- environment(fcn)
>> ll(envir=env) # ll() from R.oo
>> # member data.class dimension object.size
>> # 1 huge numeric 1000000 4000028
>> # 2 scale numeric 1 36
>>
>> save(env, file="temp.RData")
>> file.info("temp.RData")$size
>> # [1] 2007624
>>
>> I generate quite a few of these and my 'huge' objects are of order
>> 100Mb, and I want to keep memory usage as well as file sizes to a
>> minimum. What I do now, is to remove variable from the local
>> environment of 'foo' before returning, i.e.
>>
>> foo2 <- function(huge) {
>> scale <- mean(huge)
>> rm(huge)
>> function(x) { scale * x }
>> }
>>
>> fcn <- foo2(1:10e5)
>> env <- environment(fcn)
>> ll(envir=env)
>> # member data.class dimension object.size
>> # 1 scale numeric 1 36
>>
>> save(env, file="temp.RData")
>> file.info("temp.RData")$size
>> # [1] 156
>>
>> Since my "foo" functions are complicated and contains many local
>> variables, it becomes tedious to identify and remove all of them, so
>> instead I try:
>>
>> foo3 <- function(huge) {
>> scale <- mean(huge);
>> env <- new.env();
>> assign("scale", scale, envir=env);
>> bar <- function(x) { scale * x };
>> environment(bar) <- env;
>> bar;
>> }
>>
>> fcn <- foo3(1:10e5)
>>
>> But,
>>
>> env <- environment(fcn)
>> save(env, file="temp.RData");
>> file.info("temp.RData")$size
>> # [1] 2007720
>>
>> When I try to set the parent environment of 'env' to emptyenv(), it
>> does not work, e.g.
>>
>> fcn(2)
>> # Error in fcn(2) : attempt to apply non-function
>>
>> but with the new.env(parent=baseenv()) it works fine. The "base"
>> environment has the empty environment as a parent. So, I try to do
>> the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
>> once again I get
>>
>> fcn(2)
>> # Error in fcn(2) : attempt to apply non-function
>>
>> Apparently, I do not understand enough here. Please, enlighten me. In
>> the meantime I stick with foo2().
>>
>> Best,
>>
>> Henrik
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
Roger> --
Roger> Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/
Roger> ______________________________________________
Roger> R-devel at r-project.org mailing list
Roger> https://stat.ethz.ch/mailman/listinfo/r-devel
On 4/4/06, Prof Brian Ripley <ripley at stats.ox.ac.uk> wrote:
On Tue, 4 Apr 2006, Roger D. Peng wrote:
In R 2.3.0-to-be, I think you can do
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { scale * x }
environment(g) <- emptyenv()
g
}
You can, but you really don't want to and you will get the same error. A
'minimal environment' is baseenv(), since you are not going to be able to
do very much without the primitives such as * (and even "{"), and
(relevant here) you will never save anything from it so it will cost you
nothing. In this example, 'scale' is supposed to being picked up from the
environment. So (removing all the empty statements to save memory)
foo <- function(huge) {
scale <- mean(huge)
env <- new.env(parent=baseenv())
assign("scale", scale, envir=env)
bar <- function(x) { scale * x }
environment(bar) <- env
bar
}
is I think minimal baggage (and fcn saves in 153 bytes).
Thanks. For (mine and other's) record: The base environment is very
specially that it is always guaranteed to exists, and that save()
knows about this too, because it does not warn about "package ... may
not be available when loading".
In the real example I'm trying to do, my returned function calls a
function in the stats package. The naive approach is then to do:
foo <- function(huge) {
mu <- mean(huge)
parent <- pos.to.env(which("package:stats" == search()));
env <- new.env(parent=parent)
assign("mu", mu, envir=env)
bar <- function(n) { rnorm(n, mean=mu) }
environment(bar) <- env
bar
}
fcn <- foo(1:10)
print(fcn(5))
env <- environment(fcn)
save(env, file="temp.RData")
However, then you get "Warning message: 'package:stats' may not be
available when loading". To the best of my understanding right now,
it is better to use "::" as below:
foo <- function(huge) {
mu <- mean(huge)
env <- new.env(parent=baseenv())
assign("mu", mu, envir=env)
bar <- function(n) { stats::rnorm(n, mean=mu) }
environment(bar) <- env
bar
}
/Henrik
-roger Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
fcn(2)
# Error in fcn(2) : attempt to apply non-function
Apparently, I do not understand enough here. Please, enlighten me. In
the meantime I stick with foo2().
Best,
Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
-- Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
On 4/4/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
On 4/4/06, Henrik Bengtsson <hb at maths.lth.se> wrote:
On 4/4/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
On Tue, 4 Apr 2006, Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
I don't think you want to remove baseenv() from the environment. If you
do, no functions from baseenv will be visible inside fcn. These include
"{" and "*", which are necessary for your function. I think the error
message comes from being unable to find "{".
Thank you, this makes sense. Modifying Roger Peng's example
illustrates what you say:
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) x
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# [1] 2
But as soon as you add "something" to the g(), it is missing;
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { x }
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# Error in fcn(2) : attempt to apply non-function
...and I did not know that "{" and "(" are primitive functions. Interesting.
I conclude that 'env <- new.env(parent=baseenv())' is better than
''env <- new.env()' in my case.
Is there any reason to use env <- new.env(parent=baseenv()) instead of just env <- baseenv() ? The extra environment being created seems to serve no purpose.
I need to do this, because I do not want to assign 'scale' to the base
environment:
foo <- function(huge) {
scale <- mean(huge)
env <- new.env(parent=baseenv())
# cf. env <- baseenv()
assign("scale", scale, envir=env)
bar <- function(x) { scale * x }
environment(bar) <- env
bar
}
/Henrik
______________________________________________ R-devel at r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
-- Henrik Bengtsson Mobile: +46 708 909208 (+2h UTC)
On 4/4/06, Henrik Bengtsson <hb at maths.lth.se> wrote:
On 4/4/06, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
On 4/4/06, Henrik Bengtsson <hb at maths.lth.se> wrote:
On 4/4/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
On Tue, 4 Apr 2006, Henrik Bengtsson wrote:
Hi,
this relates to the question "How to set a former environment?" asked
yesterday. What is the best way to to return a function with a
minimal environment from a function? Here is a dummy example:
foo <- function(huge) {
scale <- mean(huge)
function(x) { scale * x }
}
fcn <- foo(1:10e5)
The problem with this approach is that the environment of 'fcn' does
not only hold 'scale' but also the memory consuming object 'huge',
i.e.
env <- environment(fcn)
ll(envir=env) # ll() from R.oo
# member data.class dimension object.size
# 1 huge numeric 1000000 4000028
# 2 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 2007624
I generate quite a few of these and my 'huge' objects are of order
100Mb, and I want to keep memory usage as well as file sizes to a
minimum. What I do now, is to remove variable from the local
environment of 'foo' before returning, i.e.
foo2 <- function(huge) {
scale <- mean(huge)
rm(huge)
function(x) { scale * x }
}
fcn <- foo2(1:10e5)
env <- environment(fcn)
ll(envir=env)
# member data.class dimension object.size
# 1 scale numeric 1 36
save(env, file="temp.RData")
file.info("temp.RData")$size
# [1] 156
Since my "foo" functions are complicated and contains many local
variables, it becomes tedious to identify and remove all of them, so
instead I try:
foo3 <- function(huge) {
scale <- mean(huge);
env <- new.env();
assign("scale", scale, envir=env);
bar <- function(x) { scale * x };
environment(bar) <- env;
bar;
}
fcn <- foo3(1:10e5)
But,
env <- environment(fcn)
save(env, file="temp.RData");
file.info("temp.RData")$size
# [1] 2007720
When I try to set the parent environment of 'env' to emptyenv(), it
does not work, e.g.
fcn(2)
# Error in fcn(2) : attempt to apply non-function
but with the new.env(parent=baseenv()) it works fine. The "base"
environment has the empty environment as a parent. So, I try to do
the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
once again I get
I don't think you want to remove baseenv() from the environment. If you
do, no functions from baseenv will be visible inside fcn. These include
"{" and "*", which are necessary for your function. I think the error
message comes from being unable to find "{".
Thank you, this makes sense. Modifying Roger Peng's example
illustrates what you say:
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) x
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# [1] 2
But as soon as you add "something" to the g(), it is missing;
foo <- function(huge) {
scale <- mean(huge)
g <- function(x) { x }
environment(g) <- emptyenv()
g
}
fcn <- foo(1:10e5)
fcn(2)
# Error in fcn(2) : attempt to apply non-function
...and I did not know that "{" and "(" are primitive functions. Interesting.
I conclude that 'env <- new.env(parent=baseenv())' is better than
''env <- new.env()' in my case.
Is there any reason to use env <- new.env(parent=baseenv()) instead of just env <- baseenv() ? The extra environment being created seems to serve no purpose.
I need to do this, because I do not want to assign 'scale' to the base
environment:
foo <- function(huge) {
scale <- mean(huge)
env <- new.env(parent=baseenv())
# cf. env <- baseenv()
assign("scale", scale, envir=env)
bar <- function(x) { scale * x }
environment(bar) <- env
bar
}
OK. I think the example changed throughout the discussion and
scale was not part of the latter examples.
At any rate the version with scale could be reduced to one line using evalq:
foo <- function(huge)
evalq(function(x) { scale * x }, list(scale = mean(huge)), baseenv())