1.4 两种呈现方法

将所有章节合并到一个 Rmd 文件中,这是在 bookdown 中呈现书籍的一种方法。实际上还有另一种方法:你可以在一个单独的会话中生成每一章,bookdown 将合并所有章节的 Markdown 输出文档来呈现书籍。我们将这两种方法分别称为“合并与生成” (M-K) 以及“生成与合并” (K-M)。它们之间的差异可能看起来很微妙,但根据你的用例不同可能会变得相当重要。

  • 二者最显著的差异是:M-K 在相同的 R session 中运行所有代码块,而 K-M 对于每一个独立的章节都会使用单独的 R session。对于 M-K 来说,来自前几章的 R session 状态将会转移到之后的章节(例如,前几章中创建的对象可用于后几章,除非你故意删除了它们);对于 K-M 来说,所有的章节都是相互隔离的。2如果你希望每一章都在一个干净的状态下进行编译,那么就使用 K-M 方法。如果你使用 M-K 方法,那么将一个正在运行中的 R session 恢复到完全干净的状态是非常棘手和困难的。例如,即便你 detach/unload 上一章中加载的软件包,R 也不会清除由这些软件包注册的 S3 方法。
  • 因为 knitr 不允许在一个源文档中出现重复的代码块标签,因此当你使用 M-K 方法时,需要确保在书籍各章节中没有重复的标签,否则 knitr 在生成合并后的 Rmd 文件时会发出错误信号。而 K-M 方法只需要在任何单个 Rmd 文件中没有重复的标签。
  • K-M 方法不允许 Rmd 文件位于子目录中,而 M-K 方法允许。

bookdown 中的默认方法时 M-K。如果想要转为 K-M 方法,可以在调用 render_book() 时使用参数 new_session = TRUE,或者在配置文件 _bookdown.yml 中设置 new_session: yes

对于 K-M 方法,你可以在 _bookdown.yml 中配置 book_filename 选项,但是它应该是一个 Markdown 文件的名称,例如 _main.md。不过文件扩展名并不重要,你甚至可以省略扩展名,例如,只需设置为 book_filename: _main 即可。其它配置都适用于 M-K 和 K-M。


  1. 当然,没有人能阻止你在一个章节中写出一些文件,然后在另一个章节中呈现它们。剔除这些副作用是很困难的。↩︎