+ - 0:00:00
Notes for current slide
Notes for next slide

Boost Your R Markdown Skills

Christophe Dervieux

Raukr 2021 - 21/06/2021

1 / 31

Who am I ?

Short intro

profile picture for Christophe Dervieux

Christophe DERVIEUX • France

RStudio • Software Engineer • R Markdown Team

First Time Raukr Speaker


2 / 31

Everyone should know rmarkdown among R users. Its principle has not changed since a long time (md + R = Rmd -> output format) quite easy to start (write text, add code chunk, compile) but it can be harder to learn new skill to be more efficient and get full power.

That is where known recipes can help master more advanced skills. R Markdown Cookbook was thought as a non linear documentation.

Also new logo and new pkgdown website

What happens when it renders ?

R Markdown wizard illustration by Alison Horst Source: https://github.com/allisonhorst/stats-illustrations

4 / 31

We often see these rmarkdown little wizard mixing Text & Code to produce document. Aim is to look deeper into this today. This is not so magic. It is juts percieved magic and there are tools to know about under the hood to be able to customize behavior further.

What happens when it renders ?

Diagram showing the different step of rendering

knitr::knit() + Pandoc (+ LaTeX for PDF) = rmarkdown::render()

5 / 31

rmarkdown will run Pandoc & knitr for you.

LaTeX only needed with PDF. tinytex will run it for you.

This is important to know all this because it helps know where to look and what could be tweak. one has to understand what to tweak to make something works as expected.

About the tools

We got you covered!

  • rmarkdown 📦 will install knitr and tinytex for you
  • Pandoc is an external binary tool, included inside RStudio IDE.
  • TinyTeX is the only thing to install if you want PDF output. (tinytex::install_tinytex())

In case you need it: (but you probably won't!)

6 / 31

Best to use TinyTeX as it is tested agains rmarkdown.

Everything should work as expected otherwise. No special tool needed unless for advanced usage.

Missing CTAN packages are installed by tinytex the R package.

Not sure the aim is to be a rockstar but for sure it is to make those three little guy playing together smoothly

How to boost content creation ?

Gif sayins Content is king with an illustration of a king at his desk in front of a computer with a crown dropping on his head.

8 / 31

First thing to focus one: Boost the content of the R Markdown.

Read external scripts into a chunk

About the code chunk option (1)

add <- function(x, y) {
x + y
}
```{r, code=xfun::read_utf8('my_script.R')}
```
```{r}
add <- function(x, y) {
x + y
}
```
  • This will fill the content of the chunk

  • Can be used with any engine

  • Can be used with multiple script

9 / 31

From Bookdown : https://bookdown.org/yihui/rmarkdown-cookbook/option-code.html

Useful for bigger project, or when script already exists.

Chunk content from variable

About the code chunk option (2)

Ex: Installation instruction for packages.

```{r, include = FALSE}
pkgs <- c("glue", "fs")
installation_package <- sprintf('install.packages("%s")', pkgs)
```
```{r, eval = FALSE, code = installation_package}
```

renders without evaluating to

install.packages("glue")
install.packages("fs")
10 / 31

This is just an example and this can be done with any chunk option. It is quite powerful !

Read code chunks from a script

About knitr::read_chunk()

Use a special comment syntax to label code content.

## ---- chunk-label

Ex in my_chunks.R

## ---- my-chunk-a --------
1 + 1
## ---- my-chunk-b --------
plot(cars)
Read an external script to load chunks:
```{r, include=FALSE, cache=FALSE}
knitr::read_chunk('my_script.R')
```
Now the code can be used chunk by chunk, e.g.,
```{r, my-chunk-a, echo=FALSE}
```
```{r, my-chunk-b, fig.height=4}
```
11 / 31

Useful for:

  • sharing common part of code in a script
  • Store all R code in one R file
  • For bigger project often, or when script already exists.

https://bookdown.org/yihui/rmarkdown-cookbook/read-chunk.html

Use Rmd child document

About child chunk option

Load same content in several Rmd document

```{r common-setup, include = FALSE, child = "_common.Rmd"}
```

Conditionally include a content

Change `BOSS_MODE` to `TRUE` if this report is to be read
by the boss:
```{r, include=FALSE}
# variable impacting the rendering, which could be a parameter of a report
BOSS_MODE <- FALSE
```
Conditionally include the appendix:
```{r, child=if (!BOSS_MODE) 'appendix.Rmd'}
```
12 / 31

This respect chunk option so could be useful for conditionnally eval or not a part of a document.

Also useful to organize project in smaller pieces.

https://bookdown.org/yihui/rmarkdown-cookbook/child-document.html

Dynamically create content

About knitr::knit_child()
(and result = 'asis')

## Regression on "`r x`"
```{r}
lm(mpg ~ ., data = mtcars[, c("mpg", x)])
```
  • We want to apply one linear regression between mpg and each of other variables of mtcars
    # select other variables than 'mpg'
    x_vars <- setdiff(names(mtcars), 'mpg')
  • We want the result to be included in its in own chapter.
```{r, echo=FALSE, results='asis'}
# select other variables than 'mpg'
x_vars <- setdiff(names(mtcars), 'mpg')
# knit the template for each
res <- lapply(x_vars, function(x) {
knitr::knit_child('template.Rmd',
envir = environment(), quiet = TRUE
)
})
# cat() the knitted output to be included 'asis'
cat(unlist(res), sep = '\n')
```

Can be combined with knitr::knit_expand()

```{r, echo=FALSE, results='asis'}
x_vars <- setdiff(names(mtcars), 'mpg')
res <- lapply(x_vars, function(x) {
knitr::knit_child(text = c(
'## Regression on "`r x`"',
'',
'```{r}',
'lm(mpg ~ ., data = mtcars[, c("mpg", x)])',
'```',
''
), envir = environment(), quiet = TRUE)
})
cat(unlist(res), sep = '\n')
```
13 / 31

Quite like child document but a bit different. Can be useful sometimes for programatically create markdown content.

https://bookdown.org/yihui/rmarkdown-cookbook/child-document.html

Reuse a chunk

About chunk label

Here is a code chunk that is not evaluated:
```{r, chunk-one, eval = FALSE}
1 + 1
2 + 2
```
Now we actually evaluate it:
```{r, chunk-one, eval = TRUE}
```

First chunk will be used twice - different options are allowed.

14 / 31

Reuse a figure, Show code in another place that the initial result, show figure in another place than where the plot has been evaluated. Recompute the same content.

https://bookdown.org/yihui/rmarkdown-cookbook/reuse-chunks.html

Use labels to reference chunks

About chunk ref.label

```{r chunk-b, echo = FALSE}
# this is the chunk b
1 + 1
```
```{r chunk-c, echo = FALSE}
# this is the chunk c
2 + 2
```
```{r chunk-a, ref.label = c('chunk-c', 'chunk-b'), eval = FALSE}
```
```{r chunk-a, eval = FALSE}
# this is the chunk c
2 + 2
# this is the chunk b
1 + 1
```
```
## [1] 2
```
```
## [1] 4
```
```r
# this is the chunk c
2 + 2
# this is the chunk b
1 + 1
```
15 / 31

Yes chunk content can be combined. Could be useful to show code in appendix at the end of the document for example.

https://bookdown.org/yihui/rmarkdown-cookbook/reuse-chunks.html

How to boost output styling ?

Gif of a man in a suits putting a a pink hat with included sunglasses. Text on the gif says 'You don't like my style'

16 / 31

Let's talk about styling content now.

Use CSS from inside a Rmd file

About the css engine

```{css, echo = FALSE}
/* add a blue border */
div.mybox {
border-color: blue;
border-style: solid;
padding: 0.5em;
}
/* Set to blue bold text inside the box */
div.mybox strong {
color: blue;
}
```

Applied directly in the Rmd document without an external css file

Going further: See the js engine to apply JS code the same way

17 / 31

Useful for prototyping, for quick iteration, for single file example echo = false is important if you don't want to show CSS source chunk in output

Use SASS the same way

About the sass/scss engine

What is SASS ?

Sass (https://sass-lang.com) is a CSS extension language that allows you to create CSS rules in much more flexible ways than you would do with plain CSS.

It allows for variables, tweaking functions (called mixins), operations (like /), better CSS rule organisation (nesting, extensions, ...) and more.

18 / 31

External tool used by web developers. Very powerful and this is a skill to learn when doing a lot of HTML. It can do a lot !

But no need to use it directly. Still need to learn the feature and syntax.

Use SASS the same way

About the sass/scss engine

```{css, echo = FALSE}
div.mybox {
border-color: blue;
border-style: solid;
padding: 0.5em;
}
div.mybox strong {
color: blue;
}
```
```{scss, echo = FALSE}
$color1: blue;
div {
&.mybox {
border-color: $color1;
border-style: solid;
padding: 0.5em;
strong {
color: $color1;
}
}
}
```
```{sass, echo = FALSE}
$color1: blue
div
&.mybox
border-color: $color1
border-style: solid
padding: 0.5em
strong
color: $color1
```

In both example, we are using special SASS feature like Nesting and Parent Selector.

19 / 31

The CSS is the one that would be render when using sass on the .scss or .sass file.

No preference on the syntax - it is a personnal choice (and depending on environment.)

Use SASS the same way

Powered by the new sass R 📦

https://rstudio.github.io/sass/


Support is now built-in rmarkdown

20 / 31

Quite new. Allow to use SASS from R. Wrapper around a C library.

Supported in rmarkdown now.

Use SASS the same way

Powered by the new sass R 📦

$color1: blue
div
&.mybox
border-color: $color1
border-style: solid
padding: 0.5em
strong
color: $color1
# Rendering SASS file from R
sass::sass(sass::sass_file("style.sass"))
div.mybox {
border-color: blue;
border-style: solid;
padding: 0.5em;
}
div.mybox strong {
color: blue;
}
21 / 31

Small intro. Best is to look at the pkgdown website.

Use SASS the same way

Powered by the new sass R 📦

External .sass / .scss file can also be passed in the css argument of html_document()


output:
html_document:
css: custom-style.scss

The file will be processed internally by sass::sass_file() and produce a .css automatically.

22 / 31

You can do much more with SASS. It pushes the limit of customization of a document.

How to use it ? Why this CSS example ?

Use custom blocks to style

Powered by Pandoc's fenced divs syntax

::: mybox
Special **important** content
:::

With the previous style applied, it will result in this box in the document

Special important content



<div class="mybox">
<p>Special <strong>important</strong> content</p>
</div>
23 / 31

Pandoc feature. R Markdown knows and extend it. Quite simple to write but quite powerful.

Supported by Visual editor.

Use custom blocks to style

Powered by Pandoc's fenced divs syntax

Attributes and id can be added too, e.g

::: {.mybox #box1 style="text-align: center;"}
Special **important** content
:::

The above add inline style to the div

Special important content



<div id="box1" class="mybox" style="text-align: center;">
<p>Special <strong>important</strong> content</p>
</div>

???

Allow to style mainly.

24 / 31

Aiming multi formats

About rmarkdown custom blocks for PDF support

::: {.mybox latex=true}
Special **important** content
:::
\begin{mybox}
Special \textbf{important} content
\end{mybox}

Specially supported by R Markdown and not Pandoc.

Create a LaTeX environment as easily as you can create a HTML div.

25 / 31

Extend the Pandoc feature for LaTeX environment. Not done by default in Pandoc. Special feature of rmarkdown.

Aiming multi formats

About rmarkdown custom blocks for PDF support

This requires a LaTeX preamble for this custom environment to render to PDF, e.g using tcolorbox CTAN package.

\usepackage{tcolorbox}
\newtcolorbox{mybox}{
colframe=blue,
halign=center,
boxsep=5pt,
arc=4pt}

To pass to the output format, e.g

output:
pdf_document:
includes:
in_header: preamble.tex
26 / 31

Could also be added in a file directly obviously.

Aiming multi formats

About rmarkdown custom blocks for PDF support

Using the cat engine can help you write the preamble from within the Rmd file

```{cat, engine.opts = list(file = 'preamble.tex')}
\usepackage{tcolorbox}
\newtcolorbox{mybox}{
colframe=blue,
halign=center,
boxsep=5pt,
arc=4pt}
```

This will result in the PDF as this box

27 / 31

Just for showing cat engine usage here;

And try texPreview in source file

Gif with an image from The Fresh Prince of Bel-Air wearing a pink hat and in a position of thinking with right hand of its chin. Text has been added and says 'But what about the blue bold text ?'

LaTeX customization is a topic for another time ! 🙄

28 / 31

What we've learn so far ?

Let's sum up!

Create content without repeating yourself

  • Import code chunk content from a script or from a variable
  • Use Rmd child document to share content in several places
  • Reuse some chunks several times

Customize output style

  • Customize HTML output using CSS and SASS code
  • Create and style custom blocks for HTML and PDF allowing better customization
29 / 31

How to go further ?

and boost even more your skills !

Look at examples

Xaringan Source + Demo file in
cderv/raukr-2021-rmd-boost


Or quickly try with

https://rstudio.cloud/project/2654845

30 / 31

Special demo file contains part of what we saw but also other recipes from the cookbook.

Acknowledgement

31 / 31

Who am I ?

Short intro

profile picture for Christophe Dervieux

Christophe DERVIEUX • France

RStudio • Software Engineer • R Markdown Team

First Time Raukr Speaker


2 / 31
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
oTile View: Overview of Slides
Esc Back to slideshow