これは、質問と密接に関連しています。How do I pass ``...`` to a new environment in R?異なる環境で評価された関数を返す副詞関数を書くにはどうすればよいですか?
スレッドhereです。
私の究極の目標は、機能していすることができることです。
- は機能上で動作し、機能
- を返すreturn関数は、その親
- として.GlobalEnvで新しい環境を作成します新しい環境内の引数関数を評価します。
- そして、以下で説明するセーブサイズの問題を解決します。
lm(およびggplotなどの他のオブジェクト)が呼び出し環境を保存してしまうことがあります。この環境には、無関係な情報が含まれることがよくあります。目標は、この問題を解決する便利なラッパーを用意することです。証明するために:
tmp_fun_Bill <- function(){
iris_big <- lapply(1:10000, function(x) iris)
env <- new.env(parent = globalenv())
with(env, lm(Sepal.Length ~ Sepal.Width, data = iris))
}
out <- tmp_fun_Bill()
object.size(out)
# 48008
saveSize(out)
# 4478 - this works!
私は機能を(のようなpurrr::safely
)を返し、これらの機能の一つにビルのアプローチを一般化したいと思います:
saveSize <- function (object) {
tf <- tempfile(fileext = ".RData")
on.exit(unlink(tf))
save(object, file = tf)
file.size(tf)
}
tmp_fun <- function(){
iris_big <- lapply(1:10000, function(x) iris)
lm(Sepal.Length ~ Sepal.Width, data = iris)
}
out <- tmp_fun()
object.size(out)
# 48008
saveSize(out)
# 1002448 - Far too large as it contains iris_big.
ビル・ダンラップが働くこのソリューションを提案しています。 @MrFlickからの助けを借りて
私の最高の試み、:
in_new_env <- function(.f){
function(...) {
params <- list(...)
env <- new.env(parent = globalenv())
# Change the environment of any formula objects
params <- lapply(params, function(x) {if (inherits("x","formula")) {environment(x)<-env}; x})
assign(".params.", params, envir = env)
env$.f <- .f
evalq(do.call(".f", .params.), envir=env)
}
}
tmp_fun_me <- function(){
iris_big <- lapply(1:10000, function(x) iris)
in_new_env(lm)(Sepal.Length ~ Sepal.Width, data = iris)
}
out <- tmp_fun_me()
object.size(out)
# 48008
saveSize(out)
# 1002448 - too big again
は、誰かが間違ってここに何が起こっているかを指摘することはできますか?
私にはタイプミスがありました。それは 'params < - lapply(params、function(x){if(inherits(x、" formula ")){環境(x)< - env}; x})'だったはずですが、問題。これは実際に式が作成される場所に来る。 – MrFlick