我有一个这样的计算(请注意,这只是非常简化的简化版本,最小的可复制示例!):
computation <- function() # simplified version!
{
# a lot of big matrices here....
big_matrix <- matrix(rnorm(2000*2000), nrow = 2000, ncol = 2000)
exp.value <- 4.5
prior <- function (x) rep(exp.value, nrow(x))
# after computation, it returns the model
list(
some_info = 5.18,
prior = prior
)
}
Run Code Online (Sandbox Code Playgroud)
此函数适合并返回一个模型,我想将其保存到磁盘:
m <- computation()
save(m, file = "tmp.Rdata")
file.info("tmp.Rdata")$size
# [1] 30713946
Run Code Online (Sandbox Code Playgroud)
不幸的是,如您所见,该文件太大,因为它包含函数的整个闭包prior(),并且此闭包包含函数中的所有数据computation(),包括big_matrix(在我的完整代码中有很多数据)。
现在,我尝试通过使用以下命令重新定义先前功能的环境(关闭)来修复此问题environment(prior) <- list2env(list(exp.value = exp.value)):
exp.value <- 4.5
environment(m$prior) <- list2env(list(exp.value = exp.value))
save(m, file = "tmp.Rdata")
file.info("tmp.Rdata")$size
# [1] 475
Run Code Online (Sandbox Code Playgroud)
这按预期工作!不幸的是,当我将这些清理后的代码放入calculation()函数中时(实际上,当我将此代码放入任何函数中时),它停止工作!看到:
computation <- function() # simplified version!
{
# a lot of big matrices here....
big_matrix <- matrix(rnorm(2000*2000), nrow = 2000, ncol = 2000)
exp.value <- 4.5
prior <- function (x) rep(exp.value, nrow(x))
environment(prior) <- list2env(list(exp.value = exp.value)) # this is the update
# after computation, it returns the model
list(
some_info = 5.18,
prior = prior
)
}
m <- computation()
save(m, file = "tmp.Rdata")
file.info("tmp.Rdata")$size
# [1] 30713151
Run Code Online (Sandbox Code Playgroud)
该文件再次很大,关闭未正确清除。
解决该问题的一种方法是在返回之前从环境中删除大变量。
computation <- function()
{
big_matrix <- matrix(rnorm(2000*2000), nrow = 2000, ncol = 2000)
exp.value <- 4.5
prior <- function (x) rep(exp.value, nrow(x))
rm(big_matrix) ## remove variable
list(
some_info = 5.18,
prior = prior
)
}
Run Code Online (Sandbox Code Playgroud)
list2env方法的问题是,默认情况下,它指向当前环境作为新环境的父环境,因此无论如何您都将捕获函数中的所有内容。您可以改为将全局环境指定为基本环境
computation <- function()
{
big_matrix <- matrix(rnorm(2000*2000), nrow = 2000, ncol = 2000)
exp.value <- 4.5
prior <- function (x) rep(exp.value, nrow(x))
# explicit parent
environment(prior) <- list2env(list(exp.value = exp.value), parent=globalenv())
list(
some_info = 5.18,
prior = prior
)
}
Run Code Online (Sandbox Code Playgroud)
(如果您指定emptyenv(),则将无法找到诸如的内置函数rep())