How to PDF render Quarto books with dynamic content? - r-markdown

I am writing my thesis using a Quarto book in HTML, which has some dynamic content (leaflet maps, plotly dynamic graphs). However, eventually, I will need to export the book in PDF/LaTeX, or at least Word (and then I can copy and paste into LaTeX).
When I try to export to PDF I of course run into this error:
Functions that produce HTML output found in document targeting pdf
output. Please change the output type of this document to HTML.
Alternatively, you can allow HTML output in non-HTML formats by adding
this option to the YAML front-matter of your rmarkdown file:
always_allow_html: true
Note however that the HTML output will not be visible in non-HTML
formats.
I did try to add the always_allow_html: true in my YAML file, but I get the same exact error. I also tried the conditional rendering with {.content-hidden unless-format="pdf"}, but I can't seem to get it working.
Has anyone experienced the same issue?

Using .content-visible when-format="html" and .content-visible when-format="pdf" works very smoothly.
---
title: "Conditional Rendering"
format:
html: default
pdf: default
---
## Conditional Content in Quarto
::: {.content-visible when-format="html"}
```{r}
#| message: false
library(plotly)
library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p <- p + geom_point(aes(colour = factor(cyl)))
ggplotly(p)
```
```{r}
#| message: false
#| fig-pos: "H"
#| fig-width: 4
#| fig-height: 3
library(leaflet)
# took this example from leaflet docs
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
m # Print the map
```
:::
::: {.content-visible when-format="pdf"}
```{r}
library(plotly)
library(ggplot2)
p <- ggplot(mtcars, aes(wt, mpg))
p <- p + geom_point(aes(colour = factor(cyl)))
p
```
:::

I use constructs like below
p <- ggplot()
if (interactive() || opts_knit$get("rmarkdown.pandoc.to") == "html") {
ggplotly(p)
} else {
p
}

Stumbled across this one too. I'm currently checking the output format of pandoc globally
```{r, echo = F}
output <- knitr::opts_knit$get("rmarkdown.pandoc.to")
```
and then evaluate chunks conditionally:
(leaflet example from here.)
```{r, echo = F, eval = output != "latex"}
library(leaflet)
leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=174.768, lat=-36.852, popup="The birthplace of R")
```
This is optional if you want a note on a missing component in the PDF version:
```{r, echo = F, eval = output == "latex", results = "asis"}
cat("\\textit{Please see the HTML version for interactive content.}")
```
Edit
I just checked, this also works with Quarto documents for me using the below YAML header.
---
title: "Untitled"
format:
html:
theme: cosmo
pdf:
documentclass: scrreprt
---

Related

Knit a kable to PDF in RMarkdown that includes special characters in the table values

I'm trying to format a kable that includes the permyriad sign "‱". Permyriad means 1 out of every 10,000, so 1‱ = 0.01%.
I can get it to work with the special character σ, as in the screenshot and code below. Looking for a way to replace "σ" replaced with "‱".
I am pretty sure that there exists a magical combination of the three variables what_should_this_be, should_i_escape_or_not, and id_like_to_use_booktabs that will do the trick.
I'm doing this within RStudio using the tinytex package.
Here's what I've attempted so far:
The exact value for the variable what_should_this_be that results in knitting the ‱ sign in the final pdf. The Unicode value for "‱" is U+2031.
Values I've tried:
Combinations of "\textperthousand" with varying numbers of escapes, with and without brackets, with and without opening & closing $
Copy-pasting the ‱ symbol directly with varying numbers of escapes
"\U2031" with varying numbers of escapes
Various combinations with should_i_escape_or_not set to TRUE or FALSE.
I'd like to use booktabs... but that might be asking a bit much, so I've tried various combinations setting id_like_to_use_booktabs to TRUE or FALSE.
Various combinations of setting the "Typeset LaTeX into PDF using:" option in RStudio > Tools > Sweave
```{r, echo = FALSE}
library(magrittr)
what_should_this_be <- "$\\sigma$"
should_escape_or_not <- FALSE
id_like_to_use_booktabs <- TRUE
knitr::kable(
head(mtcars) %>%
dplyr::select(mpg) %>%
tibble::rownames_to_column("car") %>%
dplyr::mutate(mpg = paste0(mpg, what_should_this_be)),
align = "cc",
escape = should_escape_or_not,
booktabs = id_like_to_use_booktabs,
caption = "Works with character $\\sigma$, but what about permyriad?"
)
```
Could use the textcomp package and \textpertenthousand
---
output:
pdf_document:
latex_engine: xelatex
header-includes:
- \usepackage{textcomp}
---
```{r, echo = FALSE}
library(magrittr)
what_should_this_be <- "\\textpertenthousand"
knitr::kable(
head(mtcars) %>%
dplyr::select(mpg) %>%
tibble::rownames_to_column("car") %>%
dplyr::mutate(mpg = paste0(mpg, what_should_this_be)),
align = "cc",
escape = F,
booktabs = T,
caption = "Works with character $\\sigma$, but what about permyriad?"
)
```

How to set df_print to tibble in markdown for a single R code chunk

I would like to show, in an rmarkdown document, the printed output of a tibble as shown in the console. i.e.
First line: dimension summary;
then the column headers;
then classes of variables;
then first 10 lines of the tibble;
then number of rows not shown.
However, by default, tibbles and other data.frame objects are automatically converted to a tabbed, paginated table showing all contents.
I note that the option to turn off this default behaviour can be set for a whole markdown document by changing the df_print option to tibble in the YAML.
However, how do I set the df_print option to tibble for just a single R code chunk, so that I can show in an Rmarkdown document what the user will see on the console?
Thanks,
Jon
There's no need to touch the global setting. You can explicitly call the print function tibble:::print.tbl_df(df)
Example:
title: "Untitled"
author: "TC"
date: "7/27/2018"
output:
html_document:
df_print: "kable"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## print tibble
```{r}
df <- tibble::as.tibble(mtcars)
tibble:::print.tbl_df(head(df))
```
## print kable (set in YAML header)
```{r}
head(df)
```
output html

Pre-populate data tables and charts using shiny_prerendered in Rmd flexdashboard

I have a shiny app created with Rmd / Flexdashboard with many charts and tables. It is working well. Recently, I started using shiny_prerendered to improve the UX during startup. Now the page loads up faster but all the sections are empty (this is expected - the html renders but the charts and tables are still waiting for data) until the server code runs.
Is it possible to have some placeholder data during setup that will load the shiny output? Reactive outputs are not recognized in the setup context. Is this what the server-start context is for? I have tried too that without success?
Here is a simple code with a two value boxes
---
title: "ValueBoxTest"
output:
flexdashboard::flex_dashboard:
vertical_layout: fill
theme: united
runtime: shiny
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, options(scipen = 1, digits = 2))
### load packages
```
# ValueBox Test
===============================================
## Row 1
### Box 1
```{r, context="server"}
output$value1 <- renderValueBox({
### p <- 100 starting value placeholder
### call function to generate "p"
p <- functionToGenerateValue()
valueBox(p, icon = "fa-usd")
})
```
```{r echo = FALSE}
valueBoxOutput("value1")
```
## Row 2
### Box 2
```{r, context="server"}
output$value2 <- renderValueBox({
### q <- 0 starting value placeholder
### call function to generate "q"
q <- functionToGenerateValue()
valueBox(q, icon = "fa-usd")
})
```
```{r echo = FALSE}
valueBoxOutput("value2")
Well, it may be simpler than you might think. For example, why don't you try to change from runtime:shiny to runtime:shiny_prerendered? It may do the trick.

R Markdown Table 1000 separator

I am trying to publish a table with 1000 separators and I am not having any luck with it. I followed the link here: Set global thousand separator on knitr but am not having much success.
My sample dataset is here: https://goo.gl/G7sZhr
The RMarkdown code is here:
---
title: "Table Example"
author: "Krishnan Viswanathan"
date: "August 4, 2015"
output: html_document
---
Load Data
{r, results='asis', message = FALSE, tidy=TRUE}
load("i75_from_flow.RData")
library(data.table)
{r, results='asis', echo=FALSE,message = FALSE, tidy=TRUE}
i75_from_flow <- i75_from_flow[order(-Tons),]
knitr::kable(i75_from_flow)
However, when I include this chunk of code (knit_hook$set) in the RMarkdown document, i get errors.
```{r, results='asis', echo=FALSE,message = FALSE, tidy=TRUE}
i75_from_flow <- i75_from_flow[order(-Tons),]
knit_hooks$set(inline = function(x) {
prettyNum(x, big.mark=",")
})
knitr::kable(i75_from_flow)
```
Error:
# object knit_hooks not found.
Any insights on what I am doing wrong and how to fix this is much appreciated.
Thanks,
Krishnan
The easiest is to use the format arguments of the kable() function itself, where you can specify the big number mark like so:
kable(df, format.args = list(big.mark = ","))
So your example would look like:
```{r, results='asis', echo=FALSE,message = FALSE, tidy=TRUE}
i75_from_flow <- i75_from_flow[order(-Tons),]
knitr::kable(i75_from_flow, format.args = list(big.mark = ","))
```
without any need for knitr hooks.
What about using pander with bunch of options to fine-tune your markdown table:
> pander::pander(i75_from_flow, big.mark = ',')
----------------------------
ORIGFIPS TERMFIPS Tons
---------- ---------- ------
12,023 12,117 5,891
12,119 12,105 4,959
12,001 12,057 3,585
12,001 12,113 3,083
12,047 12,047 1,517
----------------------------
The reason that the knit_hooks object is not found is that you either need to load the knitr package or use the knitr:: prefix in order to set the knit_hooks options. For example:
knitr::knit_hooks$set(inline = function(x) {
prettyNum(x, big.mark=",")
})

Remove Hashes in R Output from R Markdown and Knitr

I am using RStudio to write my R Markdown files. How can I remove the hashes (##) in the final HTML output file that are displayed before the code output?
As an example:
---
output: html_document
---
```{r}
head(cars)
```
You can include in your chunk options something like
comment=NA # to remove all hashes
or
comment='%' # to use a different character
More help on knitr available from here: http://yihui.name/knitr/options
If you are using R Markdown as you mentioned, your chunk could look like this:
```{r comment=NA}
summary(cars)
```
If you want to change this globally, you can include a chunk in your document:
```{r include=FALSE}
knitr::opts_chunk$set(comment = NA)
```
Just HTML
If your output is just HTML, you can make good use of the PRE or CODE HTML tag.
Example
```{r my_pre_example,echo=FALSE,include=TRUE,results='asis'}
knitr::opts_chunk$set(comment = NA)
cat('<pre>')
print(t.test(mtcars$mpg,mtcars$wt))
cat('</pre>')
```
HTML Result:
Welch Two Sample t-test
data: mtcars$mpg and mtcars$wt
t = 15.633, df = 32.633, p-value < 0.00000000000000022
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
14.67644 19.07031
sample estimates:
mean of x mean of y
20.09062 3.21725
Just PDF
If your output is PDF, then you may need some replace function. Here what I am using:
```r
tidyPrint <- function(data) {
content <- paste0(data,collapse = "\n\n")
content <- str_replace_all(content,"\\t"," ")
content <- str_replace_all(content,"\\ ","\\\\ ")
content <- str_replace_all(content,"\\$","\\\\$")
content <- str_replace_all(content,"\\*","\\\\*")
content <- str_replace_all(content,":",": ")
return(content)
}
```
Example
The code also needs to be a little different:
```{r my_pre_example,echo=FALSE,include=TRUE,results='asis'}
knitr::opts_chunk$set(comment = NA)
resultTTest <- capture.output(t.test(mtcars$mpg,mtcars$wt))
cat(tidyPrint(resultTTest))
```
PDF Result
PDF and HTML
If you really need the page work in both cases PDF and HTML, the tidyPrint should be a little different in the last step.
```r
tidyPrint <- function(data) {
content <- paste0(data,collapse = "\n\n")
content <- str_replace_all(content,"\\t"," ")
content <- str_replace_all(content,"\\ ","\\\\ ")
content <- str_replace_all(content,"\\$","\\\\$")
content <- str_replace_all(content,"\\*","\\\\*")
content <- str_replace_all(content,":",": ")
return(paste("<code>",content,"</code>\n"))
}
```
Result
The PDF result is the same, and the HTML result is close to the previous, but with some extra border.
It is not perfect but maybe is good enough.