class: center, middle, inverse, title-slide .title[ # Highlights of the knitr package from the past two years ] .author[ ###
Yihui Xie
, RStudio PBC ] .date[ ### 2022/07/27 @ rstudio::conf(2022) ] --- ## Wait, so you are not talking about any "down" packages this time? - Right, I won't let you "down" as usual (rmarkdown, bookdown, blogdown, pagedown, etc.). - Most "down" packages have had or will have equivalents in Quarto: https://quarto.org/docs/faq/rmarkdown.html - The "down" packages won't die any time soon. We will continue to maintain them. ??? Those who are familiar with my previous talks may be surprised that I'm not going to talk about "down" packages. What's up? What's down? --- ## Why talking about knitr? Because **knitr** is a common cornerstone of Quarto and R Markdown. Both of them are built on top of **knitr.**<sup>*</sup> You can apply what you have learned about **knitr** to both Quarto and R Markdown documents. .footnote[[*] Quarto can also use Jupyter.] --- background-image: url(https://yihui.org/knitr/images/knit-logo.png) background-position: right top ## Ten years of knitting - Development started [on 2011/10/16](https://github.com/yihui/knitr/graphs/contributors) - First CRAN release on 2012/01/17 - [50+ releases](https://cran.r-project.org/src/contrib/Archive/knitr/) over the years - 5000+ questions [on Stack Overflow](https://stackoverflow.com/questions/tagged/knitr) - [2000+ Github issues](https://github.com/yihui/knitr/issues) and pull requests - 100+ contributors --- ## The past two years (i.e., since COVID) - **knitr** has become quite mature, and probably inevitably boring as time goes by... - No huge new features in recent years, but a few little highlights may be worth mentioning. - For a full list, please check out the [release notes](https://github.com/yihui/knitr/releases). ??? I have almost lost track of time since the pandemic. I want to look back and see if I have done any meaningful work at all. When things become mature, they often become boring, too, such as adults. You know kids are much more fun. --- ## 1. Write chunk options in chunk body Previously, you must write all chunk options on one line in the chunk header. Now you can write them on multiple lines as special comments in the beginning of the chunk body. These comments start with `#|` (how would you pronounce this?). ??? Hash pipe? Pound bar? --- ### Before: forcing everything onto a single line... ````default ```{r, foo, echo=FALSE, fig.width=8, fig.cap="A long long caption."} plot(1:10) ``` ```` .center[![:image 70%, Drag a cat into tub](gif/drag-cat.gif)] --- ### Now: chunk options can ride with chunk body... ````default ```{r} #| foo, echo=FALSE, fig.width=8, #| fig.cap="A long long caption." plot(1:10) ``` ```` .center[![:image 40%, Jump into a car and ride](gif/get-into-the-car.gif)] --- ## You can hard-wrap lines freely ````markdown ```{r} #| foo, #| echo = FALSE, #| fig.width = 8, #| fig.cap = "A long long caption." plot(1:10) ``` ```` ````markdown ```{r} #| fig.cap = "A long long #| long long caption." plot(1:10) ``` ```` --- ## Or use YAML syntax ````markdown ```{r} #| label: "foo" #| echo: false #| fig.width: 8 #| fig.cap: "A long long caption." plot(1:10) ``` ```` For Quarto/RStudio/VSCode users, you are recommended to use the YAML syntax since 1) the editor has better support (autocomplete, validation, etc.), and 2) it works for other engines (e.g., Jupyter) and languages. --- ## Convert the old syntax to new syntax The function `knitr::convert_chunk_header()` can automatically convert your old chunk options to the new syntax (requires **knitr** >= 1.40). --- ## 2. Reuse chunk options and/or content from other chunks Previously there existed several ways to reuse the content of a code chunk, e.g., via the `ref.label` option. ````default ```{r, chunk-a} 1 + 1 ``` ```{r, chunk-b, ref.label="chunk-a"} ``` ```` You can learn more about reusing the chunk content in the [R Markdown Cookbook](https://bookdown.org/yihui/rmarkdown-cookbook/reuse-chunks.html). --- ## Reuse chunk options Now you can also reuse chunk options from other chunks via the `opts.label` option, e.g., ````default ```{r, chunk-a, fig.dim=c(10, 6), dev="svg"} plot(cars) ``` ```` Reuse chunk options from `chunk-a`: ````default ```{r, chunk-b, opts.label="chunk-a"} hist(rnorm(100)) ``` ```` --- ## Reuse both chunk options & content by passing chunk labels wrapped in `I()` to the chunk option `ref.label`, e.g., ````default ```{r, chunk-a, fig.dim=c(10, 6), dev="svg"} plot(cars) ``` ```{r, chunk-b, ref.label=I("chunk-a")} ``` ```` --- ## Quick tips 1. Both `ref.label` and `opts.label` can take a vector of chunk labels, i.e., you can reuse multiple code chunks. 2. Local chunk options will override reused options of the same names, e.g., `chunk-b` will use the `png` device instead of `svg` in the example below: ````default ```{r, chunk-a, fig.dim=c(10, 6), dev="svg"} plot(cars) ``` ```{r, chunk-b, ref.label=I("chunk-a"), dev="png"} ``` ```` --- ## 3. New chunk options in **knitr** A few new chunk options have been added to **knitr** in the past two years, and I will mention only one here: the `file` option. Sometimes you may want to develop code in an external script, and include it into a code chunk. Previously you could use the chunk option `code`, e.g., ````default ```{r, code=readLines("script.R")} ``` ```` --- Now it can be simplified to: ````default ```{r, file="script.R"} ``` ```` This option also supports a vector of file paths, e.g., ````default ```{r, file=c("script-1.R", "script-2.R")} ``` ```` --- ## 4. New engines in **knitr** The `comment` engine to comment out any content. `````default ````{comment} Arbitrary content to be commented out. ```{r} 1 + 1 ``` The above code chunk will not be executed. Inline code like `r pi * 5^2` will be ignored, too. ```` ````` --- The `verbatim` engine to write any content verbatim. `````default ````{verbatim, lang="markdown"} We can output arbitrary content verbatim. ```{r} 1 + 1 ``` The content can contain inline code like `r pi * 5^2`, too. ```` ````` -- Now please forget this old ugly hack: `````default ````markdown ```{r}`r ''` 1 + 1 ``` ```` ````` --- The `embed` engine to embed external files and display their content verbatim. ````default ```{embed, file=c("foo.R", "bar.R")} ``` ```` Alternatively, write file paths in the chunk body: ````default ```{embed} "foo.R" "bar.R" ``` ```` The advantage of the second method is that your editor (e.g., RStudio) may be able to autocomplete the file paths. --- The `exec` engine to execute an arbitrary system command on a file that contains the content of the chunk. The command is specified via the chunk option `command`, e.g., ````default ```{exec, command="bash"} echo 'Hello world!' ``` ```` That is equivalent to the existing `bash` engine in **knitr**: ````default ```{bash} echo 'Hello world!' ``` ```` A lot of [command-based engines](https://bookdown.org/yihui/rmarkdown-cookbook/other-languages.html) have existed in **knitr** (`awk`, `go`, `perl`, `zsh`, etc.). From now on, we no longer need to add a new engine for each command; [`exec` is also extensible](https://github.com/yihui/knitr-examples/blob/master/124-exec-engine.Rmd). --- The actual command executed is of the form ```bash command [args1] args [args2] ``` where `args` is a file (chunk content) by default, and `args1` / `args2` are optional command-line arguments that you may specify via the chunk option `engine.opts`, e.g., we run `grep` to match a pattern against lines of text in a chunk: ````default ```{exec} #| command = 'grep', #| engine.opts = list(args1 = c('-i', 'he')) Hello, world! This is the `exec` engine. ``` ```` --- ## Recap - Write chunk options as `#|` comments in chunk body. - Use `opts.label` to reuse chunk options, or `ref.label = I()` to reuse both options and content. - Read external files as the chunk content via `file` option. - New engines: `comment`, `verbatim`, `embed`, and `exec`. --- background-image: url(https://yihui.org/knitr/images/knit-logo.png) background-position: right 25% background-size: 20% class: center, middle # Thank you! Happy knitting! ## Questions? RStudio Community: https://community.rstudio.com, or Stack Overflow: https://stackoverflow.com ## Feature requests/bug reports? Github: https://github.com/yihui/knitr ### Slides: [slides.yihui.org/2022-rstudio-conf-knitr.html](https://slides.yihui.org/2022-rstudio-conf-knitr.html)