Reused code-chunks in Rmarkdown not working with magrittr pipe - r

The following is based on content within The R Markdown Cookbook which suggests that named code chunks can be re-used.
The following minimal (albeit contrived) example works as expected:
---
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library (magrittr)
```
```{r filterCyl, include=FALSE, eval=FALSE}
dplyr::filter(cyl == 6L)
```
```{r filterGear, include=FALSE, eval=FALSE}
dplyr::filter(gear == 4L)
```
```{r, eval=FALSE}
mtcars %>%
<<filterCyl>>
```
However, replacing the lower-most block with:
```{r, eval=FALSE}
mtcars %>%
<<filterCyl>> %>%
<<filterGear>>
```
...results in the following being shown in the resulting HTML:
mtcars %>%
<<filterCyl>> %>%
dplyr::filter(gear == 4L)
The <<filterCyl>> block is not being substituted in as I'd expect.
If I remove the %>% operators from that final block, it does get subsituted in; however, the resulting R code isn't valid.
Does this appear to be a bug? Is there some workaround that could be used here?

Related

Is there a way to export multiple gt tables to a single HTML output

I have a list of many (can be dozens of) tables created with the gt package in R. I would like to export them all as a single HTML file with a little space between each table. Currently, I have been exporting each table individually, reading them into an RMarkdown with the xfun package, and knitting to a single HTML file. I'm curious if there is a method to cut out the intermediate step of saving each table individually and reading into the Rmd.
Example:
library(gt)
library(tidyverse)
tbl_list <- list(mtcar_tbl = mtcars %>% gt(),
iris_tbl = iris %>% gt(),
cars_tbl = cars %>% gt())
purrr::map(seq_along(tbl_list), function(rownum){
htmltools::save_html(html = tbl_list[[rownum]],
file = paste0("test",rownum,".html"))
})
RMarkdown to combine and export tables:
---
title: ""
output: html_document
---
```{r, echo=FALSE,message=FALSE,warning=FALSE}
library(xfun)
```
```{r echo=FALSE}
htmltools::includeHTML("test1.html")
```
<br><br>
```{r echo=FALSE}
htmltools::includeHTML("test2.html")
```
<br><br>
```{r echo=FALSE}
htmltools::includeHTML("test3.html")
```
One option would be to use purrr::walk with chunk option results="asis" to directly print your tables without the intermediate step. To add the line breaks after each table use cat("<br><br>"):
Note: For the reprex I just print the head of each table.
---
title: "Untitled"
output: html_document
date: "2022-09-19"
---
```{r echo=FALSE, results='asis', warning=FALSE, message=FALSE}
library(gt)
library(tidyverse)
tbl_list <- list(mtcar_tbl = mtcars,
iris_tbl = iris,
cars_tbl = cars)
tbl_list <- purrr::map(tbl_list, ~ head(.x) %>% gt() )
purrr::walk(tbl_list, function(x) { print(x); cat("<br><br>") })
```

Rmarkdown to docx less-than symbol in table caption

I would like to use the < symbol in a table caption of a Rmarkdown that converts to a docx document. I am using the flextable package as this gives a lot of (needed) flexibility to tables in the docx format.
But I am really confused by the multiple conversion steps through pandoc. It does not seem so easy to get to the < as it is a special coding HTML character. I have read that in HTML you would escape it via <. This gives me the problem that the & has to be escaped, too. The conversion then turns < into &lt; (as it converts the & into &) and \\< would yield me &amp;lt; (as it converts the & of the & again). Latex does not seem to work either, I've tried <, $<$ and $\\textless$ but to no avail.
All combinations basically follow the same logic, i.e. that < are correctly transformed to < but then the HTML is not converted again.
Any idea how to solve this? What do I miss?
Example RMD file:
---
title: "Untitled"
author: "Unkown"
date: "1/25/2021"
output: bookdown::word_document2
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(flextable)
library(tidyverse)
```
## R Markdown
This is an R Markdown document, see Table \#ref(tab:test).
```{r test, echo = F}
flextable(head(cars, n = 10)) %>%
bold(part = "header") %>%
autofit() %>%
set_caption("Table: (\\#tab:test) Example caption with less-than symbol: \\< or < or < or $<$ or $\\textless$")
```
This should answer the question about < and > in the captions
---
title: "Untitled"
output: bookdown::word_document2
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(flextable)
library(tidyverse)
```
## R Markdown
This is an R Markdown document, see Table \#ref(tab:test).
```{r test, echo = F, tab.id="test"}
flextable(head(cars, n = 10)) %>%
bold(part = "header") %>%
autofit() %>%
set_caption("Example caption with less-than symbol: > and <")
```
You could use the package officedown. It will make the references as real Word references, it also offers few features to customize your captions:
---
output:
bookdown::markdown_document2:
base_format: officedown::rdocx_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, tab.cap.style="Table Caption")
library(flextable)
library(tidyverse)
```
```{r test1}
flextable(head(cars, n = 10)) %>%
bold(part = "header") %>%
autofit() %>%
set_caption("Example caption with less-than symbol: > and <")
```
```{r "test2", tab.cap="Example caption with less-than symbol: > & <"}
flextable(head(cars, n = 10)) %>%
bold(part = "header") %>%
autofit()
```
\newpage
See \#ref(tab:test1).
See \#ref(tab:test2).

Printing any number of dataframes stored in list as paged tables in rmarkdown

I often want to print out the dataframes contained in a list as paged tables in my rmarkdown documents. Calling each dataframe individually renders the desired ouptut if the right df_print option is selected. However, the point of having a list is that the number of dataframes varies depending on the parameters passed to the rmarkdown document; so that's no real solution.
Based on Vincent Guyader's answer to this question and on this example of rmarkdown::paged_table, I've tried to do the following without success.
Is there a way to achieve this at all? I'd be happy to use any package that supports pagination remotely resembling the df_print option.
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
```
### Desired output but impossible to generalise
```{r}
df_list[["cars"]]
```
```{r}
df_list[["flowers"]]
```
### datatable shows as blanks on the page
```{r}
map(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```
### rmarkdown outputs dataframe contents as one very long string
```{r}
map(df_list, rmarkdown::paged_table)
```
The issue is that the JS dependencies needed to render the Datatable are not included in the HTML output. A workaround which I borrowed from here is to add a code chunk
```{r init-step, include=FALSE}
DT::datatable(mtcars)
```
outside of the loop or map statement which ensures that the JS dependencies are included. Also, I would recommend to switch to purrr::walk as using map has the effect that the tables are plotted twice.
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
```
### Desired output but impossible to generalise
```{r}
df_list[["cars"]]
```
```{r}
df_list[["flowers"]]
```
### datatable shows as blanks on the page
```{r init-step, include=FALSE}
DT::datatable(mtcars)
```
```{r}
walk(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```
When using results='asis' argument, the renderer (here DT) has to be initialized once before being applied on a asis list.
This seems to be a general problem, see here with leaflet, and here with Highcharter.
The answer to this general question has been given here.
In this case:
---
title: "Printing paged tables from a list of dataframes in Rmarkdown"
output:
html_document:
df_print: paged
---
```{r,}
library(DT)
library(rmarkdown)
library(purrr)
library(knitr)
df_list <- list("cars" = mtcars, "flowers" = iris)
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, message = FALSE, results='asis')
# initialize the renderer
data.frame() %>%
DT::datatable() %>%
knitr::knit_print() %>%
attr('knit_meta') %>%
knitr::knit_meta_add() %>%
invisible()
```
```{r , results='asis'}
#Remove already printed element and print the rest
df_list[[1]] <- NULL
map(df_list, ~DT::datatable(.x) %>%
htmltools::tagList() %>%
print())
```

how can I show my "ztable" when I use "knit to HTML" in R?

I am having a problem with my ztable,
I want to knit my Rmarkdown file to HTML but I cannot find a way to display the table I created with ztable:
z=ztable(loucaste) %>% makeHeatmap(palette = "Blues") %>% print(caption="Table 2.)
I tried to set
options(ztable.table="html")
and put this at the beginning as I read somewhere else
output: html_document
header-includes: \usepackage{colortbl}
but it doesn't work when I knit to HTML. My intention was to create a sort of formatting table similar to the ones made on excel and ztable looks like the only way.
Try this minimal Rmd. The key seems to be options(ztable.type = "html") and in the chunk that generates the table, r results='asis'
If that works for you, substitute your code in the appropriate place i.e. ztable(loucaste) %>% makeHeatmap(palette = "Blues") %>% print(caption="Table 2.).
---
title: "ztable"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(ztable)
library(magrittr)
options(ztable.type = "html")
```
## R Markdown
```{r results='asis'}
matrix(1:100, nrow = 10) %>%
as.data.frame() %>%
ztable() %>%
makeHeatmap() %>%
print(caption = "table 2")
```

how to use a for loop in rmarkdown?

Consider this simple example:
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
## Slide with R Output
```{r t, warning=FALSE, message=FALSE}
library(knitr)
library(kableExtra)
library(dplyr)
for(threshold in c(20, 25)) {
cars %>%
filter(dist < threshold) %>%
kable('html') %>%
kable_styling(bootstrap_options = "striped")
}
```
Here I simply want to print each output of the for loop into a different slide. In this example, there are two calls to kablethat should go on two different slides.
The code above does not work. Am I even using the right packages for that? Any ideas?
Thanks!
You can use the asis option:
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)
library(dplyr)
# needed so r will include javascript/css dependencies needed for striped tables:
kable(cars, "html") %>% kable_styling(bootstrap_options = "striped")
```
```{r, results = "asis"}
for (threshold in c(20, 25)) {
cat("\n\n##\n\n")
x <- cars %>%
filter(dist < threshold) %>%
kable('html') %>%
kable_styling(bootstrap_options = "striped")
cat(x)
}
```
To get rid of that bogus table, you can try to put options(kableExtra.html.bsTable = T) in your setup section.
Here's the start of a solution. You can print strings with markdown, either by making the strings yourself or using pander's pandoc.* functions. If you set results="asis" for that chunk, it will get compiled the same as any other markdown. I used cat to make the ## headings, but commented out two pander functions that you could try also to make headers or horizontal rules to split slides.
There's more detail on the pander functions here, plus other SO questions such as this one.
---
title: "Untitled"
output: ioslides_presentation
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)
library(dplyr)
```
```{r, results='asis'}
for(threshold in c(20, 25)) {
# pander::pandoc.header(sprintf("Threshold = %s", threshold))
# pander::pandoc.horizontal.rule()
cat(paste("\n##", "Threshold =", threshold), "\n")
tbl <- cars %>%
filter(dist < threshold) %>%
kable(format = "html") %>%
kable_styling(bootstrap_options = "striped")
print(tbl)
}
```
One issue is that when I knit this, I'm not getting the striped table that you'd expect. If I add a slide before this chunk and put a table in it with these kableExtra settings, I do get stripes, but the first table is also pretty ugly...I'm not sure if that's a bug or conflicting CSS somewhere or what.

Resources