Retrieving RMarkdown YAML metadata

Understanding RMarkdown’s metadata object and the yamlthis package.

Author

María Paula Caldas

Published

April 13, 2020

Modified

November 28, 2022

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:

ymlthis::as_yml(rmarkdown::metadata)
#> ---
#> 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
#> ---

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)
copy_yaml <- function(input, ...) {
  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.

create_with_yaml <- function(input, output, ...) {
  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!

Footnotes

  1. Thanks to this answer by Christophe Dervieux on RStudio Community.↩︎