0

我有一个适合模型的函数,我用相同的大矩阵多次调用该模型(每次在内部创建不同的公式)。然而,似乎 R 保存了我一路使用的数据的副本,所以我的记忆爆炸了。

函数内部的简单删除可以避免这个问题。但是,有没有一种通用的方法可以避免每次都保留整个环境?

例如,运行以下命令,

test <- function(X, y, rm.env=F){
  df <- cbind(y, X)
  names(df) <- c("label", paste0("X", as.character(1:ncol(X))))
  f <- formula(label~1, data=df, env=emptyenv())
  if (rm.env){
    rm(list=c("df", "X", "y"))
  }
  print(pryr::object_size(f))
  return(f)
}

X <- matrix(rnorm(700*10000), ncol=700)
y <- rnorm(10000)

m <- test(X, y)
print(pryr::object_size(m))

m <- test(X, y, rm.env=T)
print(pryr::object_size(m))

结果是,

672 B
168 MB
672 B
1.13 kB

请注意,第一次调用中的对象后面有 168 MB,因此一遍又一遍地调用第一个版本会很快消耗大量内存。

4

1 回答 1

1

formula(label~1, data=df, env=emptyenv())调用 S3 方法formula.formula。我们来看看它的代码:

stats:::formula.formula
# function (x, ...)
# x

……多余的参数被忽略了!

换句话说,你的作业和你写的一样f = label ~ 1。特别是,它的关联环境是本地环境,而不是空环境。要解决此问题,您需要手动重置它:

test <- function (X, y) {
  df <- cbind(y, X)
  names(df) <- c("label", paste0("X", seq_along(X)))
  # TODO: do something with `df` …
  f <- label ~ 1
  environment(f) <- emptyenv()
  f
}
于 2021-02-17T11:51:11.907 回答