【问题标题】:knitr: starting a fresh R session to clear RAMknitr:开始一个新的 R 会话以清除 RAM
【发布时间】:2012-10-09 02:25:28
【问题描述】:

我有时会处理很多对象,由于块之间的内存问题,如果有一个新的开始会很好。考虑以下示例:

警告:我有 8GB 的​​ RAM。如果你没有太多,这可能会吃光它。

<<chunk1>>=
a <- 1:200000000
@
<<chunk2>>=
b <- 1:200000000
@
<<chunk3>>=
c <- 1:200000000
@

这种情况下的解决方法是:

<<chunk1>>=
a <- 1:200000000
@
<<chunk2>>=
rm(a)
gc()
b <- 1:200000000
@
<<chunk3>>=
rm(b)
gc()
c <- 1:200000000
@

但是,在我的示例中(我可以发布,因为它依赖于大型数据集),即使在我删除所有对象并运行 gc() 之后,R 也不会清除所有内存(仅部分) .原因在?gc:

However, it can be useful to call ‘gc’ after a large object has
been removed, as this may prompt R to return memory to the
operating system.

注意重要的词mayR 有很多情况会像这样指定may,所以这不是错误。

是否有一个块选项可以让knitr 启动一个新的R 会话?

【问题讨论】:

  • 也许如果您调用(从块中)Rscript 并使用代码以可以延迟加载的方式保存这些对象?
  • 如果为每个块启动一个新的 R 会话,在一个块中创建的对象将无法用于任何其他块,那么将所有这些对象放在同一个文档中的意义何在?顺便说一句,cache=TRUE 将保存对象并稍后延迟加载它们,这不会消耗您的内存,除非您以后真正使用这些对象(在手册中解释:github.com/downloads/yihui/knitr/knitr-manual.pdf)。你试过这个选项吗?
  • @Yihui 是的,我试过了。问题不在于重复编译(缓存会有所帮助)。问题在于只编译一次。为了回答您关于重点是什么的问题,我认为想要模块化您的代码和您的写作是可以理解的。这是对您的问题的编程类比响应:当您可以将所有内容放入 main 时,为什么要将您的代码模块化分解为不同的函数或不同的 .c 文件?
  • @XuWang 我理解模块化,但我不理解你的类比。我的意思是,如果您在新的 R 会话中启动它们,您的“模块”将彼此完全独立,即您将无法在本文档后面实际使用任何“模块”,那么为什么要放他们在本文档中吗?
  • @Yihui 我明白你的意思。我会重新考虑我的代码。感谢您的帮助以及您在 knitr 上所做的工作!

标签: r knitr


【解决方案1】:

我的建议是为每个主要任务创建一个单独的.Rnw,将它们编织到.tex 文件中,然后在parent.Rnw 文件中使用\include\input 来构建完整的项目。通过makefile控制项目的构建。

但是,为了解决这个特定问题,为每个块使用新的 R 会话,您可以使用 R 包 subprocess 来生成 R 会话,运行所需的代码,提取结果,然后终止生成的会话.

一个简单的例子.Rnw文件

\documentclass{article}
\usepackage{fullpage}
\begin{document}

<<include = FALSE>>=
knitr::opts_chunk$set(collapse = FALSE)
@

<<>>=
library(subprocess)

# define a function to identify the R binary
R_binary <- function () {
  R_exe <- ifelse (tolower(.Platform$OS.type) == "windows", "R.exe", "R")
  return(file.path(R.home("bin"), R_exe))
}
@


<<>>=
# Start a subprocess running vanilla R.
subR <- subprocess::spawn_process(R_binary(), c("--vanilla --quiet"))
Sys.sleep(2) # wait for the process to spawn

# write to the process
subprocess::process_write(subR, "y <- rnorm(100, mean = 2)\n")
subprocess::process_write(subR,  "summary(y)\n")

# read from the process
subprocess::process_read(subR, PIPE_STDOUT)

# kill the process before moving on.
subprocess::process_kill(subR)
@


<<>>=
print(sessionInfo(), local = FALSE)
@

\end{document}

生成以下pdf:

【讨论】:

    猜你喜欢
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    • 2012-04-20
    相关资源
    最近更新 更多