Run an R Markdown based on interactive parameter choice - r

I am trying to do the following on R Markdown. Basically, I would like the user to be able to select between two values of a parameter called "Machine" and based on the value selected run some chunks and not others. I know that the "eval" option might be useful here but I have no clue on how to use it in order to reach my goal.
My code for the moment is this (in R Markdown):
---
title: "SUM and SAM"
output: html_document
params:
machine:
label: "Machine"
value: SUM
input: select
choices: [SUM, SAM]
printcode:
label: "Display Code:"
value: TRUE
date: !r Sys.Date()
data:
label: "Input dataset:"
value: None
input: file
years_of_study:
input: slider
min: 2018
max: 2020
step: 1
round: 1
sep: ''
value: [2018, 2019]
---
```{r setup, include=FALSE}
############# IMPORTANT ###################################
#Remember to Knit with Parameters here using the "Knit button"--> "Knit with Parameters".
####################################################
#If you only want the parameters to be shown, run the following.
#knit_with_parameters('~/Desktop/Papers/git_hub/sum_sam.Rmd')
#This must be left uncommented if we want to show the content of the Markdown file once "Knit with Parameters" is pressed.
knitr::opts_chunk$set(echo = TRUE)
Say now I would like a chunk that will execute only if machine = SAM. How can I do that?
Was thinking about something like:
{r pressure, echo=FALSE, eval=params$machine}
plot(pressure)
but does not work
Thank you,
Federico

Let there be a file called foo.Rmd with this content:
---
title: "SUM and SAM"
output: html_document
params:
machine:
input: select
choices: [SUM, SAM]
value: SUM
---
```{r, eval = params$machine == "SAM", echo=FALSE}
print("SAM was chosen")
```
```{r, eval = params$machine == "SUM", echo=FALSE}
print("SUM was chosen")
```
Then you can do:
rmarkdown::render("foo.Rmd", params = list(machine = "SAM"))
Alternativeley, there is the option knit with parameters in RStudio:
Resulting in foo.html:

Related

Run RMarkdown (.rmd) from inside another .rmd without creating HTML output

I am making my code more modular and would like to run multiple RMarkdown files from one overall RMarkdown. I believe I could do this if I translated all my RMarkdown files to .R scripts and used source(), but I like the document-like nature of RMarkdown and I can describe what I'm doing as I'm doing it in plain text.
The goal is to wrangle data and export a usable .sav file. I want to run clean.rmd from run.rmd, but I don't want any HTML/pdf/etc. output. Removing the output line in the YAML header doesn't prevent output. If there is a way to do this without translating everything to .R scripts, I would be very appreciative. Thank you.
clean.rmd: Script that does the cleaning
---
title: "clean"
author: "jrcalabrese"
date: "12/30/2021"
output: html_document
---
```{r}
library(tidyverse)
library(haven)
```
```{r}
data(cars)
cars <- cars %>%
mutate(newvar = speed + dist)
```
```{r}
write_spss(cars, "~/Documents/cars_new.sav", compress = FALSE)
```
run.rmd: Script that runs clean.rmd
---
title: "run"
author: "jrcalabrese"
date: "12/30/2021"
output: html_document
---
```{r}
rmarkdown::render("~/Documents/clean.rmd")
```
Thank you for your help! This function works:
---
title: "run"
author: "jrcalabrese"
date: "12/30/2021"
#output: html_document
---
```{r}
source_rmd = function(file, ...) {
tmp_file = tempfile(fileext=".R")
on.exit(unlink(tmp_file), add = TRUE)
knitr::purl(file, output=tmp_file)
source(file = tmp_file, ...)
}
```
```{r}
source_rmd("~/Documents/clean.rmd")
```

plots after dynamic sections using R Markdown pander, knitr and pandoc

I use this rmd:
---
title: "Some Title"
author: "Some Author"
date: "`r format(Sys.time(), '%d-%m-%Y')`"
---
## A function that generates sections
```{r setup, include = FALSE}
library(pander)
create_section <- function() {
# Inserts "## Title (auto)"
pander::pandoc.header('Title (auto)', level = 2)
# Section contents
# e.g. a random plot
plot(sample(1000, 10))
# a list, formatted as Markdown
# adding also empty lines, to be sure that this is valid Markdown
pander::pandoc.p('')
pander::pandoc.list(letters[1:3])
pander::pandoc.p('')
}
```
## Generate sections
```{r, results='asis', echo=FALSE}
n_sections <- 3
for (i in seq(n_sections)) {
create_section()
}
```
and then:
library(knitr);
library(rmarkdown);
setwd("C:/bla")
knit('test_md.Rmd')
rmarkdown::pandoc_convert("test_md.md", to = "pdf", output = "test_pdf.pdf")
This kind of works but the plots are all rendered after the sections:
Each section should contain the plot. Any ideas? Thanks!
PS:
Wrapping:
plot(sample(1000, 10))
in print:
print(plot(sample(1000, 10)))
forces output to be produced. Unfortunately, NULL is also printed underneath the plot.
Could you just add pdf_document in the YAML and then generate the PDF by knitting?
---
title: "Some Title"
author: "Some Author"
date: "`r format(Sys.time(), '%d-%m-%Y')`"
output: pdf_document
---
I was able to get the same result you described when running the rmarkdown::pandoc_convert() on the .md file, all the plots at the end of the .PDF file.

Parameters in Knitr

I'm trying to write a Rmarkdown code in which the user interactively inserts an excel table and, then a report is automatically generated. First, in the YAML I've written:
---
title: "Test"
author: "Test"
date: "Test"
output: html_document
params:
data:
label: "Insert your data:"
value: results.csv
input: file
---
Then, in the chunk 1 I've used:
```{r ,warning= FALSE, message=FALSE, echo=FALSE }
library(tidyverse)
rmarkdown::render('Test.Rmd', params = 'ask')
df = as.data.frame(readxl::read_excel(params$data))
```
While running this code aforementioned, the navigator opens with a browser to input the file, and there are two buttons "cancel" and "save" (should it not be 'Knit'?)
When I 'save', the output is: "Error params object already exists in knit environment so can't be overwritten by render params"
Therefore, I've tried:
```{r ,warning= FALSE, message=FALSE, echo=FALSE }
library(tidyverse)
rmarkdown::render('Test.Rmd', params = 'ask', envir = new.env())
df = as.data.frame(readxl::read_excel(params$data))
```
Again, I insert the data file and the output is: Error in parse_block(g[-1], g[1], params.src, markdown_mode) : Duplicate chunk label 'setup', which has been used for the chunk: knitr::opts_chunk$set(echo = TRUE) Calls: ... process_file -> split_file -> lapply -> FUN -> parse_block
I'm not finding the issue and why it is happening. Could someone help me?

Hide comments in R markdown

Is is possible to hide some comments in code when kniting using knitr / R markdown? Example:
---
title: "SOSO"
author: "SO"
date: '2017-06-06'
output: pdf_document
---
```{r}
# Generate some data
rnorm(2)
## But keep this comment
```
When kniting I would like the first comment to disapear, but keep the second one somehow.
Here is a quick example of modifying the hook to change knitr behavior.
---
title: "SOSO"
author: "SO"
date: 2017-06-06
output: pdf_document
---
```{r setup-hook, echo=FALSE}
hook_in <- function(x, options) {
x <- x[!grepl("^#\\s+", x)]
paste0("```r\n",
paste0(x, collapse="\n"),
"\n```")
}
knitr::knit_hooks$set(source = hook_in)
```
```{r}
# Generate some data
# Lines that starts with `# ` will be removed from the rendered documents
rnorm(2)
## But keep this comment
## But lines that starts with `## ` will be kept
```
produces this
In fact, you can choose to show any lines of R code by passing numeric indices to the chunk option echo, e.g.
---
title: "SOSO"
author: "SO"
date: '2017-06-06'
output: pdf_document
---
```{r echo=4:7}
# Generate some data
rnorm(2)
## But keep this comment
```
See knitr documentation for more information.

RMarkdown accessing parameter from bash chunk

I created an RMarkdown file file.Rmd with parameters.
I know how to access parameters within a r chunk but not from a bash chunk
If there is absolutely no way to do so, I will write the parameters in a file through r chunk and then read it from bash chunk...
---
output: html_document
params:
myParam1:
label: "Choose 1st parameter"
value: 20
input: slider
min: 0
max: 100
myParam2:
label: "Choose 2nd parameter"
value: "Hello"
input: text
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r, echo=FALSE}
print(paste("1st parameter :",params$myParam1))
print(paste("2nd parameter :",params$myParam2))
```
```{bash}
# Don't know how to get parameters here
echo $params
```
Thanks
I've seen a few options
Use Sys.setenv to export variables from R to bash, so add this line to an R chunk.
Sys.setenv(params = params$myParam1)
Use the runr package
To apply the export-to-envirnoment idea from the accepted answer to all params, just add the following do.call loop to an R chunk before the bash chunk:
```{r, echo=FALSE, message=FALSE}
for (key in names(params)) {
do.call('Sys.setenv', params[key])
}
```
Thanks Chris S, this works fine.
I share the workaround I used (create tmp file) in case someone would be interested :
---
output: html_document
params:
myParam1:
label: "Choose 1st parameter"
value: 20
input: slider
min: 0
max: 100
myParam2:
label: "Choose 2nd parameter"
value: "Hello"
input: text
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Chris solution :
```{r, echo=FALSE}
Sys.setenv(param1=params$myParam1)
Sys.setenv(param2=params$myParam2)
```
```{bash, echo=FALSE}
echo $param1
echo $param2
```
My workaround :
```{r}
param1 <- paste0("param1=\"",params$myParam1,"\"")
param2 <- paste0("param2=\"",params$myParam2,"\"")
# Write parameters in temporary file
fileConn <- file("~/params.tmp")
writeLines(c(param1,param2), fileConn)
close(fileConn)
```
```{bash, echo=FALSE}
. ~/params.tmp
rm ~/params.tmp
echo $param1
echo $param2
```

Resources