Home > OS >  Dynamically naming the output file in a custom R-markdown function
Dynamically naming the output file in a custom R-markdown function

Time:02-19

I found the function below here. It works great, but I would like to dynamically name the output file 'analysis.docx', using the title of the document, the author and the current date.

title: thetitle
author: myinititals
date: "`r Sys.Date()`"
knit: (function(inputFile, encoding) { 
          out_dir <- 'test';
          rmarkdown::render(inputFile,
                            encoding=encoding, 
                            output_file=file.path(dirname(inputFile), out_dir, 'analysis.docx')) })

How do I make 'analysis.docx' dynamic in this case?

I found some more information here, but not my desired answer.

CodePudding user response:

If the fields that you want to use don't include R expressions, you can use yaml_front_matter() to extract their values and use those to construct the name for the output file:

---
title: "Untitled"
author: "Jane Doe"
date: "18/02/2022"
output: word_document
knit: >
  (function(input_file, encoding) {
    metadata <- rmarkdown::yaml_front_matter(input_file)
    output_file <- with(metadata, paste(title, "by", author))
    rmarkdown::render(input = input_file, output_file = output_file)
  })
---

204 No Content

If your fields do include R expressions, this becomes a little more involved. You can apply the same principle, but now instead of getting the front matter from the RMarkdown file, you get it from the intermediate Markdown file generated during the rendering process. Then rename the result.

That could look something like this:

---
title: "Untitled"
author: "Jane Doe"
date: "`r Sys.Date()`"
output: word_document
knit: >
  (function(input_file, encoding) {
    # Render, keeping intermediate files for extracting front matter
    md_dir <- tempdir()
    output_file_temp <- rmarkdown::render(
      input = input_file,
      output_file = tempfile(),
      intermediates_dir = md_dir,
      clean = FALSE
    )
    
    # Get the rendered front matter from the intermediate Markdown file
    md_file <- fs::path_ext_set(fs::path_file(input_file), ".knit.md")
    metadata <- rmarkdown::yaml_front_matter(fs::path(md_dir, md_file))
    
    # Build the output file name based on rendered metadata
    output_name <- with(metadata, paste(title, "by", author, "on", date))

    # Add the file extension and move to the working directory
    output_ext <- fs::path_ext(output_file_temp)
    output_file <- fs::path_ext_set(output_name, output_ext)
    fs::file_move(output_file_temp, output_file)

    message("Output moved to: ", output_file)
  })
---

204 No Content
  • Related