带有外部和嵌入式 yaml 的 RMarkdown

Posted

技术标签:

【中文标题】带有外部和嵌入式 yaml 的 RMarkdown【英文标题】:RMarkdown with both external and embedded yaml 【发布时间】:2021-07-29 17:23:50 【问题描述】:

我正在尝试创建一系列文档(例如书籍章节),其中每个章节都是在 Rmarkdown (.Rmd) 文档中创建的。这些文档中的每一个都包含一个 yaml 标题,我希望它采用章节标题(我有一个自定义 pandoc 模板 .html 文档,因此 yaml 标题中的chapter: 提供了章节名称)。因此每个文档的顶部看起来像:

---
title: "This is my book"
author: "A. Student"
chapter: "Chapter 1: Genesis"
output:
  html_document:
    template: my_template.html
---

然后我有一个 R 脚本,它会提升我目录中的所有 .Rmd 文档并通过 render() 函数运行它们。

for(i in list.files(pattern = "[.]Rmd%")
  rmarkdown::render(input=i, output_dir="outputs")

yaml 标头中各章之间唯一不同的部分是变量chapter 的值,其他一切都保持不变。我想用一个外部 yaml 文件来运行它来确定变量标题、作者、输出和模板,同时在每个 .Rmd 文档中嵌入一个单独的 yaml 标题,给出章节名称。因此,我创建了一个 yaml 文档 main.yaml,其中包含上述所有内容(不包括章节变量),仅在 .Rmd 文档 yaml 标头中留下章节变量,并运行 render() 并包含 output_yaml="main.yaml" 参数。但是,它似乎根本无法获取 main.yaml 文件的内容——这不可能吗?我认为也许 .Rmd yaml 标头的排名高于外部?

我的目标是通过更改 main.yaml 文档来轻松更新所有输出的输出类型、模板文档、书名或作者变量。


注意,即使没有嵌入的 yaml,它似乎也无法获取我的 main.yaml 文件

【问题讨论】:

你不能每次都创建一个新的 rmarkdown 书。如果你想更新所有这些参数,那不就是每次都渲染一本新书吗? Main.yaml 真的只是每本书/更新的 yaml 吗?我喜欢 BluVoxe 使用参数的回答 【参考方案1】:

不幸的是,我认为rmarkdown::render() 不允许您轻松覆盖 yaml 标头中的任意字段或为它们引用外部文件,尽管这将是一个不错的功能。一种解决方法是使用 params 字段在文档的最顶部传递参数,然后在整个 yaml 标头中引用这些参数。如果您不想引用外部 yaml 文件,这还允许您指定默认值。所以你的 .Rmd 标头看起来像这样:

---
params:
  chapter: "Chapter 1: Genesis"
  title: "This is my book"
  author: "me"
title: '`r params$title`'
author: '`r params$author`'
chapter: '`r params$chapter`'
---

您可以像这样使用外部 yaml 文件:

rmarkdown::render("test.Rmd", params = yaml::read_yaml("main.yml"))

main.yml 看起来像这样:

chapter: "a new chapter"
title: "a new title"
author: "someone else"

请注意,您无法使用此方法更改output,但这实际上是render()output_yamloutput_options 参数的预期用途。仔细阅读 render() 文档,了解如何在单独的 yaml 文件中指定输出选项。

【讨论】:

以上是关于带有外部和嵌入式 yaml 的 RMarkdown的主要内容,如果未能解决你的问题,请参考以下文章

Rmarkdown YAML 中的引号和内联 R 代码

用于 rmarkdown 的 YAML 中的内联 R 代码不运行

编织 RMarkdown 文档时出现 YAML 错误 - 扫描仪错误

使用 Shiny 链接到 RMarkdown 上的本地 html 文件

可以在交互式 rmarkdown 文档中使用 knitr 缓存块吗?

r Markdown的Yaml标头中的单引号和双引号有啥区别?