Reputation: 4169
I am trying to create a series of documents (e.g. book chapters) where each chapter is created in an Rmarkdown (.Rmd) document. Each of these documents contains a yaml header where I would like it to take a chapter title (I have a custom pandoc template .html document, so chapter:
in the yaml header provides the chapter name). Therefore the top of each document looks like:
---
title: "This is my book"
author: "A. Student"
chapter: "Chapter 1: Genesis"
output:
html_document:
template: my_template.html
---
I then have an R script which lifts all the .Rmd documents in my directory and runs them through the render()
function.
for(i in list.files(pattern = "[.]Rmd%"){
rmarkdown::render(input=i, output_dir="outputs")
}
The only part of the yaml header that differs between the chapters is the value of the variable chapter
, everything else remains the same. I would like to run this with an external yaml file to determine the variables title, author, output and template, while having a separate yaml header embedded within each .Rmd document giving the chapter name. I therefore created a yaml document, main.yaml, containing all of the above excluding the chapter variable, left only the chapter variable in the .Rmd document yaml header and ran render()
with the output_yaml="main.yaml"
argument included. However, it simply doesn't seem to pick up the contents of the main.yaml file - is it not possible to do this? I'm think that perhaps the .Rmd yaml header outranks that external?
I aim to do this so I can easily update the output type, template document, book title or author variables across all outputs by just changing the main.yaml document.
Note, it doesn't seem to pick up my main.yaml file even without the embedded yaml
Upvotes: 4
Views: 1363
Reputation: 2748
Unfortunately I don't think rmarkdown::render()
allows you to easily override arbitrary fields in the yaml header or reference an external file for them, though this would be a nice feature. A workaround is to use the params
field to pass in your arguments at the very top of your document and then reference these params throughout the yaml header. This would also allow you to specify defaults in case you don't want to reference your external yaml file. So your .Rmd header would look something like this:
---
params:
chapter: "Chapter 1: Genesis"
title: "This is my book"
author: "me"
title: '`r params$title`'
author: '`r params$author`'
chapter: '`r params$chapter`'
---
And you could use an external yaml file like so:
rmarkdown::render("test.Rmd", params = yaml::read_yaml("main.yml"))
Where main.yml
would look like this:
chapter: "a new chapter"
title: "a new title"
author: "someone else"
Note that you won't be able change the output
with this method, however this is actually the intended use of the output_yaml
and output_options
arguments to render()
. Have a careful read through the render()
documentation to see how you can specify output options in a separate yaml file.
Upvotes: 4