Rmarkdown将输出文件定向到目录中

30

我发现了一个非常棒的技巧(链接),可用于 knitr 的一个功能,你可以将输出的 html 保存到输出文件夹下并使用不同的文件名。

你唯一需要在头部添加的是以下内容:

title: "analysis"
author: "Me"
date: "`r format(Sys.time(), '%d %B, %Y, %H:%M')`"
knit: (function(inputFile, encoding) { 
      rmarkdown::render(inputFile,
                        encoding=encoding, 
                        output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })
output:
  html_document:
    number_sections: yes
    toc: yes

这段代码在我的Mac上有时能够很好地运行,但有时会遇到找不到out_dir变量的问题...

我最初考虑先执行代码块,以便设置变量...但这并没有解决问题...

我也尝试过重新启动R会话,但没有帮助。

最后一步是关闭R,并保存工作区,在重新打开R并加载工作区后,它就像魔术般地正常工作了。

我无法找到最初的帖子,在那里有人推荐了这个技巧...

重现完整流程:

打开一个新项目,将其命名为test并放在一个新文件夹中
创建一个r markdown文档
将标题更改为:

---
title: "Untitled"
author: "Me"
date: "`r format(Sys.time(), '%d %B, %Y, %H:%M')`"
knit: (function(inputFile, encoding) { 
      rmarkdown::render(inputFile,
                        encoding=encoding, 
                        output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })
output:
  html_document:
    number_sections: yes
    toc: yes
---

```{r write quant output files}
out_dir <- 'test'
if(!file.exists(out_dir)) {
  dir.create(out_dir)
}
```

将文档保存为test.Rmd
点击knit按钮(html现在从按钮选项中移除)
这将失败!

关闭项目!
点击保存环境!

打开项目并单击knit!
一切正常。

执行rm(list=ls()),之后所有内容都能正常工作。


1
想象在一个干净的 R 会话中运行该代码。如果您没有定义 out_dir,那么 R 如何知道它是什么?当重新加载工作区后这段代码能够正常工作时,这是因为 out_dir 是从上一个 R 会话中传递过来的对象,这使得代码能够正常工作,尽管本不应如此。 - Thomas
你说得没错,但是命令在 rmakrdown 过程中被评估,当 HTML 被创建时。我也可以手动设置变量 out_dir,但仍然存在相同的问题,Rstudio 抱怨 out_dir 不存在... 如果脚本运行一次,我也可以执行 rm(list=ls()),之后它也能正常工作... 所以我认为这不仅仅是设置变量的问题... - drmariod
如果你不指定那个变量,这段代码根本无法运行。如果没有完整的工作流程描述,很难说它为什么能够运行。 - Thomas
我添加了正确的工作流程。这真的很奇怪,因为如果我至少重新打开项目,一切都能正常工作......不确定是否有其他人可以重现这个问题......但对我来说也没有具体意义。我只是认为,该命令将在整个Markdown处理过程的最后被评估... - drmariod
刚刚找到了原始技巧的链接 - drmariod
2个回答

28

你可以尝试在传递给knit渲染的函数中设置out_dir变量:

knit: (function(inputFile, encoding) { 
      out_dir <- 'test';
      rmarkdown::render(inputFile,
                        encoding=encoding, 
                        output_file=file.path(dirname(inputFile), out_dir, 'analysis.html')) })

我的意思是,重新打开R项目后,我的整个函数/ rmarkdown都可以正常工作...即使我删除了已经设置的整个环境...所以我想知道为什么会发生这种情况。或者有人无法重现我发布的场景吗?我在Mac和两台Windows计算机上尝试过,并且在所有计算机上都可以重现并在重新打开R项目后工作。 - drmariod
是的,如果我不设置“out_dir”变量,它就无法在我的机器上运行。 - NicE
4
我会将 if(!file.exists(out_dir)) { dir.create(out_dir) } 这部分直接加入到编织函数中。这样做对我很有效,而且这么做也有点合理:你把所有的编织内容放在头部,可以在主体中使用你的内容 - 这应该是正确的做法。 - Julian
我有点喜欢这个不错的版本,我还按照Julian建议给我的函数添加了if exists部分,看起来运行得很好...只是我想知道,为什么在render函数中设置的out_dir变量也可以在我的代码块中使用?我在想,如果我在函数中设置了它,是否需要设置两次...但经过几次测试,这个变量似乎真的是可用的。所以我只需要设置一次...有人能解释一下吗?我原以为这个变量应该对外部是不可见的。 - drmariod
1
out_dir是非常可定制化的。你甚至可以将它写到其他目录中,例如:out_dir = '../reports'; - Kay
显示剩余3条评论

4

我发现写输出文件名很麻烦,所以我将 output_file 参数换成了 output_dir,但保留了其他代码。这样我的 Rmarkdown 仍然被编织到子目录中,但使用了 inputFile 名称。另外,如果目录不存在,则会创建该目录。

---
title: "title"
author: "gordon freeman"
date: "`r Sys.Date()`"

knit: (function(inputFile, encoding) {
      out_dir <- "reports";
      rmarkdown::render(inputFile,
                        encoding=encoding,
                        output_dir=file.path(dirname(inputFile), out_dir))})
---

这几乎是完美的,但是如果您在Rmarkdown文件中的r块中使用缓存,则缓存目录仍会在项目级别生成 :-( - Hugues

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接