Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to store embedded file (includes) in custom Rmarkdown

Tags:

r

r-markdown

I created my own format in Rmarkdown based on this blogpost. I implemented it in my personal package and it works great. I also added custom files in includes argument of html_document.

My question is whether it's possible to store my custom files (included in includes argument) after I click Knit button. Similarly to self_contained = F option which allows storing all Rmarkdown dependencies.

Update

I should give you some context first. Let’s say I used my html format to create a report two months ago. Two weeks later I decided to implement major changes in my html format and updated my package.

After next two weeks, my boss came to me asking for adding minor changes in old report. Then, by clicking Knit button, the report was not able to create, because there was a new version of my html format, which was significantly different.

I see three possibilities how to deal with this request. Either I can install old version of my package (suboptimal), create a new html format every time I implement major changes or I can store my dependencies (header, footer, css files) in a separate subdirectory (like a packrat). Then each report would be independent and immune to changes in my custom format.

Let me know if there is any better solution.

like image 675
Nicolabo Avatar asked Nov 23 '17 13:11

Nicolabo


People also ask

How do I embed code into R Markdown?

You can insert an R code chunk either using the RStudio toolbar (the Insert button) or the keyboard shortcut Ctrl + Alt + I ( Cmd + Option + I on macOS).

How do I save a file as Markdown in R?

To create an R Markdown report, open a plain text file and save it with the extension . Rmd. You can open a plain text file in your scripts editor by clicking File > New File > Text File in the RStudio toolbar. Be sure to save the file with the extension .

How do you save plots in R Markdown?

You want to make sure that you save images you create in your rmarkdown document. To do this automatically, and avoid writing things like ggsave(plot) or dev. off() , just create the plots in rmarkdown, and tell it you want to save the output. In the funky looking code at the top, the YAML, specify keep_md: yes .


1 Answers

Basic example

Assume that you have a myreport.Rmd file with the following header:

---
title: "Untitled"
author: "Romain Lesur"
date: "27 janvier 2018"
output: 
  html_document:
    includes:
      in_header: inheader.html
---

Using a hacky rmarkdown preprocessor, you can copy inheader.html file.
The following code is intended to be run in R console:

pre_processor <- function(metadata, 
                          input_file, 
                          runtime, 
                          knit_meta, 
                          files_dir, 
                          output_dir) {

  in_header <- metadata$output$html_document$includes$in_header
  if (!is.null(in_header)) file.copy(in_header, output_dir)

  invisible(NULL)
}

custom_output_format <- function() {
  rmarkdown::output_format(
    knitr = NULL,
    pandoc = NULL,
    pre_processor = pre_processor,
    base_format = rmarkdown::html_document()
  )
}

rmarkdown::render('myreport.Rmd', 
                   output_format = custom_output_format(), 
                   output_dir = 'output')

You get a output directory with the rendered report and inheader.html file inside.

In order to run a similar preprocessor on clicking Knit button, you have to include it in your personal package's output_format (see below).

Turning in a package

As the question mentions this blogpost, here is an adaptation of the quarterly_report function:

quarterly_report <- function(toc = TRUE) {

  # get the locations of resource files located within the package
  css <- system.file("reports/styles.css", package = "mypackage")
  header <- system.file("reports/quarterly/header.html", package = "mypackage")

  # call the base html_document function
  base_format <-
    rmarkdown::html_document(toc = toc,
                             fig_width = 6.5,
                             fig_height = 4,
                             theme = NULL,
                             css = css,
                             includes = includes(before_body = header))

  pre_processor <- function(metadata,
                            input_file,
                            runtime,
                            knit_meta,
                            files_dir,
                            output_dir) {
    purrr::walk(c(css, header), file.copy, output_dir)

    invisible(NULL)
  }

  rmarkdown::output_format(
    knitr = NULL,
    pandoc = NULL,
    pre_processor = pre_processor,
    base_format = base_format
  )
}

This solution is not 100% satisfying because I don't think that rmarkdown pre_processor was created for having side-effects. But it works.

like image 60
RLesur Avatar answered Nov 05 '22 10:11

RLesur