Passing function in rmarkdown parameter to render plots in html report - r

I am passing plots generated from shiny to rmarkdown to generate html report. The trouble is wordcloud and pie chart are being accepted in params in rmarkdown document.
Question : How to pass wordcloud and pie plots in rendered html via shiny ?
abc.Rmd
title: "Report using R Markdown"
subtitle: "ABC "
author: "Author name"
output:
prettydoc::html_pretty:
theme: architect
params:
wc : 'NULL'
table: 'NULL'
pie: 'NULL'
app.R(snippet)
rmarkdown::render(input = "report.Rmd",
output_file = "report.html",
params = list(wc=getWordcloud(),
table=getTab(),
pie=getPie()))
Note : getWordcloud(),getTab(),getPie() function are returning plots perfectly in shiny app.

You can't have as a parameter type a function.
See here in parameter type:
http://rmarkdown.rstudio.com/developer_parameterized_reports.html
All of the standard R types that can be parsed by the yaml::yaml.load function are supported including character, integer, numeric, and logical.
I strongly recommend to find a way to make your code working without the need to pass a function in the parameter. Maybe you can pass options of the function and include the function in the rmd?
But, there is ways to bypass that:
One is to use in the parameter the name of the function as a string and to use eval() to evaluate the string as code.
abc.Rmd
title: "Report using R Markdown"
subtitle: "ABC "
author: "Author name"
output:
prettydoc::html_pretty:
theme: architect
params:
wc : wc_function
table: table_function
pie: pie_function
eval(paste0(param$wc_function, "(", my_options_as_string, ")"))
app.R(snippet)
rmarkdown::render(input = "report.Rmd",
output_file = "report.html",
params = list(wc="getWordcloud",
table="getTab",
pie="getPie"))
Another one is to have another r script with the functions, called in the rmarkdown with source.
That way, you can pass the path of the file as a parameter and it allows you to get access to your function inside the rmarkdown (but it implies the name of the functions are fixed)

Related

Highlighting some references in RMarkdown documents?

Is it possible to emphasise (e.g., put in bold) some references that contain a particular string (e.g., the name of a particular author) in a papaja .Rmd document (where the refs are taken from a bib file and using the apa7.csl file)?
I can propose this solution based on pandoc lua filter which would work for not just pdf but also html output and doesn't require manual editing of latex or html file.
---
title: "The title"
bibliography: "r-references.bib"
output:
pdf_document:
pandoc_args: [ "--lua-filter", "ref-bold.lua"]
html_document:
pandoc_args: [ "--lua-filter", "ref-bold.lua"]
---
```{r setup, include = FALSE}
library("papaja")
r_refs("r-references.bib")
```
We used `R` [#R-base] and `Tidyverse` [#R-tidyverse] for all our analyses. Especially [#R-tidyverse] made things easy.
\vspace{10mm}
# References
ref-bold.lua
function Cite(el)
if pandoc.utils.stringify(el.content) == "[#R-tidyverse]" then
return (pandoc.Strong(el))
end
end
This demo bolds all of the reference to tidyverse package, if we would wanted to bold the reference to base-R, we would modify the second line in ref-bold.lua as pandoc.utils.stringify(el.content) == "[#R-base]" and all instances of references to base-R would be bold (highlighted).
pdf output
html output
A Lua-Filter would be the most elegant solution. If you use BibLaTeX and biber, you can use the general annotation feature (see this SO answer).
Include the following in your preamble:
\renewcommand*{\mkbibnamegiven}[1]{%
\ifitemannotation{bold}
{\textbf{#1}}
{#1}}
\renewcommand*{\mkbibnamefamily}[1]{%
\ifitemannotation{bold}
{\textbf{#1}}
{#1}}
In your bib-file, use the Author+an field to define which author to highlight:
#Misc{pawel2022power,
title = {Power Priors for Replication Studies},
author = {S Pawel and F Aust and L Held and E J Wagenmakers},
year = {2022},
eprinttype = {arxiv},
eprint = {2207.14720},
url = {https://arxiv.org/abs/2207.14720},
Author+an = {2=bold}
}
Now, render the R Markdown file with XeLaTeX, keep the intermediate files and the TeX file, and render the TeX file again using biber:
rmarkdown::render("paper.Rmd", clean = FALSE)
tinytex::xelatex("academic.tex", bib_engine = "biber")
Posting a solution in case it can be useful to others as well. We can first render the LaTeX file from the RMarkdown document, then find and replace all instances of the name to be emphasised, and finally generate the pdf from the modified LaTeX file.
# knitting the original Rmd file (with "keep_tex: true" in YAML)
rmarkdown::render(input = "some_file.Rmd")
# reading the generated LaTeX file
tex_file <- readLines(con = "some_file.tex")
# putting a particular author in bold in the references list
new_tex_file <- gsub(pattern = "James, W.", replace = "\\textbf{James, W.}", x = tex_file, fixed = TRUE)
# writing the (updated) LaTeX file
writeLines(text = new_tex_file, con = "some_file.tex")
# generating the pdf file (may need to be ran twice)
system(command = "xelatex some_file.tex")

How to pass logical parameters with the Quarto R package to the knitr chunk options via a parameterized Quarto document in R

I've provided a minimal reproducible example below. I'm currently trying to use the R quarto package to pass a logical parameter into the Quarto chunk options.
Below is the quarto document, where I created 2 parameters, show_code, and show_plot.
---
title: "Untitled"
format: html
params:
show_code: TRUE
show_plot: TRUE
---
```{r, echo=params$show_code}
summary(cars)
```
```{r, include=params$show_plot}
plot(pressure)
```
This document would render properly via the render button in R studio.
However, when trying to render this document via the quarto_render() function from the R quarto package, this would fail.
library(quarto)
quarto::quarto_render(
input = 'qmd_document.qmd',
output_format = 'html',
output_file = 'qmd_document_with_code.html',
execute_params = list(show_plot = TRUE,
show_code = TRUE)
)
It appears that a character yes is passed instead of the logical TRUE or FALSE to both Chunk 1 and Chunk 2 in the console.
How do I properly pass the logical characters to a parameterized Quarto report chunk options via quarto_render()?
Option 1 (Using chunk options in chunk header)
We can use logical statement in chunk option (as we do in r-markdown).
parameterized_report.qmd
---
title: "Using Parameters"
format: html
params:
show_code: "yes"
show_plot: "yes"
---
```{r, echo=(params$show_code == "yes")}
summary(cars)
```
```{r, include=(params$show_plot == "yes")}
plot(pressure)
```
Then from either r-console/rscript file, we call quarto_render using params "yes" or "no",
quarto::quarto_render(
input = 'parameterized_report.qmd',
output_format = 'html',
output_file = 'qmd_document_with_code.html',
execute_params = list(show_plot = "yes",
show_code = "no")
)
Option 2 (Using YAML syntax chunk option)
Note that, above we have used the chunk option in the chunk header which works fine with knitr engine, but quarto prefers comment-based yaml syntax (i.e. using #|). As per the quarto documentation
Note that if you prefer it is still possible to include chunk options on the first line (e.g. ```{r, echo = FALSE}). That said, we recommend using the comment-based syntax to make documents more portable and consistent across execution engines. Chunk options included this way use YAML syntax rather than R syntax for consistency with options provided in YAML front matter. You can still however use R code for option values by prefacing them with !expr
So following the quarto preferred way, we can use parameters like this,
parameterized_report.qmd
---
title: "Using Parameters"
format: html
params:
show_code: "false"
show_plot: "false"
---
```{r}
#| echo: !expr params$show_code
summary(cars)
```
```{r}
#| include: !expr params$show_plot
plot(pressure)
```
then use quarto_render with "true" or "false"
quarto::quarto_render(
input = 'parameterized_report.qmd',
output_format = 'html',
output_file = 'qmd_document_with_code.html',
execute_params = list(show_plot = "true",
show_code = "true")
)
Lastly, note two things,
here we have used "true" or "false", since echo, include, eval takes value true/false instead of TRUE/FALSE in this comment-based syntax.
Additionally, Since knitr 1.35, knitr engine also supports this comment based syntax. See News from knitr v1.35 to v1.37: Alternative Syntax for Chunk Options

Any way to set rmarkdown::paged_table() as the deafult way to printing table?

I have seen a tutorial by which one can change the way tables are printed to knitr::kable() format. Is it possible to do the same with the rmarkdown::paged_table() format, so that all tables by default will be printed in paged_table() format as in the {rmarkdown} package in R?
I had the same problem in Quarto and the solution is to use df-print: paged (note df-print not df_print) in the yaml file.
Eg.
---
title: "Untitled"
editor: visual
format:
html:
df-print: paged
---
```{r}
data.frame(
x = 1:10,
y = rnorm(10)
)
```
which results in this
In case of Rmarkdown the answer offered by #VishalKatti is IMHO the way to go. For Quarto (or RMarkdown), adapting the example in the R Markdown Cookbook one option to achieve your desired result may look like so:
---
title: Use a custom `knit_print` method to print data frames
format: html
---
First, we define a `knit_print` method, and register it:
```{r}
knit_print.data.frame = function(x, ...) {
res = rmarkdown::paged_table(x)
rmarkdown:::knit_print.data.frame(res)
}
registerS3method(
"knit_print", "data.frame", knit_print.data.frame,
envir = asNamespace("knitr")
)
```
Now we can test this custom printing method on data frames.
Note that you no longer need to call `rmarkdown::paged_table()`
explicitly.
```{r}
head(iris)
```
```{r}
head(mtcars)
```
Put this in the yaml.
output:
html_document:
df_print: paged
To complete the answer shared above, here are several ways to achieve this
Using a printing function for knitr
For paged table this would be this function: (which is used internally by rmarkdown for the df_print feature)
paged_print <- function(x, options) {
knitr::asis_output(
rmarkdown:::paged_table_html(x, options = attr(
x,
"options"
)),
meta = list(dependencies = rmarkdown::html_dependency_pagedtable())
)
}
This is similar to the function in the other answer, it is just that rmarkdown:::knit_print.data.frame does more than juts handling paged tables.
Then you could register it in a document so that it is applied by default for any data.frame printing.
registerS3method(
"knit_print", "data.frame", paged_print,
envir = asNamespace("knitr")
)
or use it on chunk basis where you need to print a data.frame in a single value chunk. (
```{r, render = paged_print}
iris
```
More on custom printing method for knitr its vignette
Using option hooks for knitr
A df_print chunk option can also be simulated this way using a option hook
knitr::opts_hooks$set(df_print = function(options) {
if (options$df_print == "paged") {
options$render = paged_print
}
options
})
this will allow something like
```{r, df_print = "paged"}
iris
```
```{r}
iris
```
First table will be shown as paged table
Second table will be show as usual data.frame

knitr::is_word_output() to check if the current output type is word – just like knitr::is_latex_output() and knitr::is_html_output()

knitr::is_latex_output() and knitr::is_html_output() allow checking if the current output type LaTex or HTML respectively.
Is there an equivalent for Word as an output format?
If not, what would be the most simple to use workaround?
---
title: "MWE for different file formats in namespace:knitr"
output:
pdf_document: default
html_document: default
word_document: default
---
```{r}
if (knitr::is_html_output()) {
cat("HTML")
}
if (knitr::is_latex_output()) {
cat("LATEX")
}
if (knitr::is_word_output()) {
cat("WORD")
}
## Error: 'is_word_output' is not an exported object from 'namespace:knitr'
```
As of knitr 1.31 (released in January 2021), you can use knitr::pandoc_to() in either of the following ways:
```{r}
if (knitr::pandoc_to("docx")) {
cat("Word")
}
```
```{r, include=knitr::pandoc_to("docx")}
cat("Word")
```
To conditionally output literal text content (rather than R code), it's easiest to use an asis chunk (note that we need to use the echo option instead of include):
```{asis, echo=knitr::pandoc_to("docx")}
This will only appear in Word documents.
```
```{asis, echo=knitr::pandoc_to("docx", "pdf")}
This will be appear in Word and PDF documents.
```
Historical answer
In earlier versions of knitr, you can use an internal knitr function to get the type you want:
is_word_output <- function(fmt = knitr:::pandoc_to()) {
length(fmt) == 1 && fmt == "docx"
}

How do I insert a variable image file in a rmarkdown pdf

The problem is simple - How do I insert a variable filename into an rmarkdown PDF? I want to do this:
---
FNL = "image.png"
---
![Some Text](params$FNL)
only I need to pass in the value for FNL when calling rmarkdown::render
The purpose is to give the image a unique ID so that users get images marked for their session.
Anyone able to help with this?
Just use inline R evaluation (works for both HTML and PDF output):
---
title: "Example"
author: "Martin"
date: "March, 11 2017"
output: html_document
params:
img: NULL
---
`r sprintf("![A good boy](%s)", params$img)`
Then you can render the document with the image file by calling
rmarkdown::render("MyDocument.Rmd", params = list(img = "unnamed.png")).

Resources