::as_yml(rmarkdown::metadata)
ymlthis#> ---
#> title: Retrieving RMarkdown YAML metadata
#> author: María Paula Caldas
#> date: '2020-04-13'
#> date-modified: '2022-11-28'
#> categories:
#> - rmarkdown
#> - ymlthis
#> description: |
#> Understanding RMarkdown's metadata object and the yamlthis package.
#> image: |
#> https://images.unsplash.com/photo-1544383835-bda2bc66a55d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1136&q=80.jpg
#> image-alt: |-
#> Photo by Jan Antonin Kolar on Unsplash.
#> https://unsplash.com/photos/lRoX0shwjUQ
#> ---
I recently discovered two nice features of the rmarkdown package that deal with the YAML metadata of R Markdown documents: the metadata
object and the yaml_front_matter()
function. Both of these are generally used “behind the scenes” in the code of other R packages, but I found them very useful in my day-to-day reporting workflow. In this post, I will explain my understanding of these objects, and I will show a couple of helper functions I created with the ymlthis package.
Using metadata
in R Markdown templates
The metadata
object returns the YAML metadata of the current R Markdown document as a list. Keep in mind that this object is only created in the knit environment, i.e. when you render your document. For example, this post has the following metadata specified at the top of the file:
Calling metadata
will return a list with this metadata when we knit the document.
library(rmarkdown)
metadata#> $title
#> [1] "Retrieving RMarkdown YAML metadata"
#>
#> $author
#> [1] "María Paula Caldas"
#>
#> $date
#> [1] "2020-04-13"
#>
#> $`date-modified`
#> [1] "2022-11-28"
#>
#> $categories
#> [1] "rmarkdown" "ymlthis"
#>
#> $description
#> [1] "Understanding RMarkdown's metadata object and the yamlthis package.\n"
#>
#> $image
#> [1] "https://images.unsplash.com/photo-1544383835-bda2bc66a55d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1136&q=80.jpg\n"
#>
#> $`image-alt`
#> [1] "Photo by Jan Antonin Kolar on Unsplash.\nhttps://unsplash.com/photos/lRoX0shwjUQ"
In an interactive R session, metadata
will return an empty list.
Usually, we will refer to metadata
parameters in inline code calls. For example, the following line in the source document
> This post was written on `r format(as.Date(metadata$date), '%B %d, %Y')`.
will be rendered as
This post was written on April 13, 2020.
I have found the metadata
object to be particularly useful when creating templates. A great example is the xaringan template of the rstudio::conf2019 workshops. RStudio’s template defines the title, subtitle, author and tutorial session in the YAML front matter of the R Markdown document, and later refers back to these objects via metadata
to create the first slide of the presentation. This makes it easier to adapt the template as the main document parameters are defined at the top of the R Markdown file.
You may have noticed that metadata
is similar to the params
list used in parametrised reports. The main difference between the two is that params
is designed for iteration. This is because the fields specified in params
can be easily overridden via rmarkdown::render()
. If you want to learn more about parametrised reports, I recommend the bookdown book, or Mike Smith’s Talk from rstudio::conf2019. If you are interested in how metadata
and params
came to be, have a look at issue #33 of the rmarkdown package.
Copying defaults with yaml_front_matter()
and ymlthis
The yaml_front_matter()
function returns a list with the YAML metadata of any R Markdown file. Unlike metatdata
, yaml_front_matter()
also works outside of the knit environment.
yaml_front_matter("index.qmd") # provide file path
#> $title
#> [1] "Retrieving RMarkdown YAML metadata"
#>
#> $author
#> [1] "María Paula Caldas"
#>
#> $date
#> [1] "2020-04-13"
#>
#> $`date-modified`
#> [1] "2022-11-28"
#>
#> $categories
#> [1] "rmarkdown" "ymlthis"
#>
#> $description
#> [1] "Understanding RMarkdown's metadata object and the yamlthis package.\n"
#>
#> $image
#> [1] "https://images.unsplash.com/photo-1544383835-bda2bc66a55d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1136&q=80.jpg\n"
#>
#> $`image-alt`
#> [1] "Photo by Jan Antonin Kolar on Unsplash.\nhttps://unsplash.com/photos/lRoX0shwjUQ"
I was very excited when I learned about yaml_front_matter()
1 because it allowed me to write a helper function for a repetitive task that I do all the time: opening up previous R Markdown document with a configuration I like, copying its YAML metadata, and using it to create or update another RMarkdown file.
To do this, I took advantage of the ymlthis package, which provides tools to write YAML metadata of R Markdown documents.
library(ymlthis)
<- function(input, ...) {
copy_yaml |>
input yaml_front_matter() |> # get the YAML metadata
yml() |> # transform list to yml object
yml_replace(...) |> # replace fields specified in ...
use_yml() # copy YAML header to clipboard
}
The copy_yaml()
function defined above lets me grab the YAML metadata of any R Markdown document, update the fields that I wish to change, and get have the updated YAML header copied to my clipboard.
copy_yaml(
"index.qmd",
title = "New title",
author = "María Paula Caldas"
)#> ---
#> title: New title
#> author: María Paula Caldas
#> date: '2020-04-13'
#> date-modified: '2022-11-28'
#> categories:
#> - rmarkdown
#> - ymlthis
#> description: |
#> Understanding RMarkdown's metadata object and the yamlthis package.
#> image: |
#> https://images.unsplash.com/photo-1544383835-bda2bc66a55d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1136&q=80.jpg
#> image-alt: |-
#> Photo by Jan Antonin Kolar on Unsplash.
#> https://unsplash.com/photos/lRoX0shwjUQ
#> ---
#> • Paste into R Markdown or YAML file
I also wrote a similar function that creates a new R Markdown file with the YAML specifications of another.
<- function(input, output, ...) {
create_with_yaml |>
input yaml_front_matter() |>
yml() |>
yml_replace(...) |>
use_rmarkdown(output) # creates an Rmd file
}
Although simple, I find myself using these functions relatively often. I will definitely be looking more into ymlthis to see how I take advantage of more of its functionalities!