How to run a rmarkdown to create multiple html with different parameters? - r

I have a code in R, which is done in rMarkdown, it needs to run several times but with different parameter values.
How can I solve it? I have put an example of simplified problems.
Suppose I need to print different values in a loops, in order to make it simple I used simple loops.
For each combination of these two loops I want to make one html file, for example means 200 *400 different html report files.
---
title: "file1"
author: "user"
date: "25 1 2021"
output: html_document
---
# The first loop should be done, from 1:100, 101:200 ... to ... 20001:20100
```{r}
i=getfirst()
j=getsecond()
```
```{r}
for (i in i:j) print(i)
```
# The second loop should be done, from 1:50, 51:100 ... to ... 20001:20050
```{r}
for (i in i-50:j-50) print(i)
```
suppose each time we may have different i and j which should pass into markdown file.

I'd simply create a wrapper script (i.e. a separate e.g. .R) file, where you specify:
R file
for (i in 1:10){
j = i+50
if(!dir.exists(paste0("directory_",i))){dir.create(paste0("directory_",i))}
knitr::knit(input = "markdown.Rmd",output = paste0("directory_",i,"/output",i,"_",j,".html"))
}
And then your Rmd file, which you have saved as markdown.Rmd in this example looks like this:
RMarkdown file
---
title: "file1"
author: "user"
date: "25 1 2021"
output: html_document
---
# The first loop should be done, from 1:100, 101:200 ... to ... 20001:20100
```{r}
for (i in i:j) print(i)
```
# The second loop should be done, from 1:50, 51:100 ... to ... 20001:20050
```{r}
for (i in i-50:j-50) print(i)
```

There is a dedicated chapter in the official documentation, "Knitting with parameters", that outlines how to proceed in your use-case.

Related

Creating R Markdown htmls by looping

I have a large report that I am running through R Markdown. The report has a data frame. At the beginning of the script, the data frame is filtered. After that, it does lots of manipulation and interpretation.
Currently, I change what I filter for and knit each report individually. I want to automate this process so that I can provide a vector of terms to filter with and the reports are generated.
Here is an example:
---
title: "Create markdown htmls with loop"
author: "Nathan Roe"
date: "2/17/2022"
output: html_document
---
library(dplyr)
my_df <- data.frame(my_letters = letters[1:5], my_numbers = 1:5)
my_df %>% filter(my_letters == "a")
I want to generate reports for a, b, c, d, and e. Currently, I have to go in and change what is being filtered for. As shown in the example above, I am filtering for "a". After that, I would have to change it to filter for "b", and so on. Is there a way to automate this, so that I provide a vector a, b, c, d, and e and reports are generated based on those filters and htmls are generated using the letter as the title. For example, I provide my_letters <- letters[1:5] and the script creates a.html, b.html, c.html, d.html, and e.html.
It seems similar to this, https://community.rstudio.com/t/loop-for-output-files/79716, but this example is poorly explained, if it does even answer the question.
The link you mention gives all the elements to generate a parametrized report.
On your example, you could knit with custom parameters using rmarkdown::render.
markdown file : test.Rmd
---
title: "Create markdown htmls with loop"
author: "Nathan Roe"
date: "2/17/2022"
output: html_document
params:
letter: 'a'
---
# `r paste('Processing letter ',letter)`
```{r}
letter
```
html file generation with loop :
for (letter in letters[1:5] ) {
rmarkdown::render(input = 'test.Rmd',
output_file = paste0(letter,".html"),
params = list(letter = letter))
}
...

Knitr output differs between Rmd and Rnw: data.table output example

Revised title to clarify focus.
We notice an anomaly that R markdown and data.table interact in a surprising way. Same does not happen when knitting LaTeX. Commands which not have a return within the R session do cause a return within the knitted markdown output. I trace the problem back to commands like the following, which do not produce an output in R,
````{r}
poolballs[ , weight2:=2 * weight]
```
but inside Rmarkdown, the output includes the full print of the poolballs DT. Same does not happen if we knit an equivalent chunk in LaTeX.
This produced some funny HTML output because I wrote chunks like this, intending to display only the first 5 lines
```{r}
poolballs[ , weight2:=2 * weight]
head(poolballs)
```
Markdown parses that as the equivalent of two chunks,
> poolballs[ , weight2:=2 * weight]
> poolballs
> head(poolballs)
Here's the markdown file to demonstrate
---
title: "Data Table Guide"
author:
- name: Paul Johnson
affiliation: Center for Research Methods and Data Analysis, University of Kansas
email: pauljohn#ku.edu
date: "`r format(Sys.time(), '%Y %B %d')`"
output:
html_document:
theme: united
highlight: haddock
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=TRUE, comment=NA)
options(width = 70)
```
```{r make_pb_dt}
set.seed(234234)
library(data.table)
poolballs <- data.table(
number = 1:15,
weight = rnorm(15, 45.7, 0.8),
diameter = c(3, 2.9, 3.1) #shows recyling
)
poolballs
```
I want the following to show only head in line 2
```{r}
poolballs[ , weight2:=2 * weight]
head(poolballs)
```
Compare the HTML output:
http://pj.freefaculty.org/scraps/mre-dt.html
I'm sorry if this is a known feature of markdown. I've coded around this wrinkle by hiding chunks, but it seems somewhat inconvenient. Today i'm curious enough to ask you about it. I wrote the same chunks in a LaTeX file and the funny DT output problem does not happen. I put link to PDF from LaTeX in http:/pj.freefaculty.org/scraps/mre-dt-3.pdf
In your final chunk, knitr sees that you have two objects that its attempting to print and you're getting the output for both. This isn't a feature, and has been addressed in a previous question.
If you want to only print the head of the first object in that chunk, your code should be head(poolballs[, weight2:=2 * weight])

Calling an .Rmd file from within an .Rmd file

I have a standard piece of analysis to perform on multiple datasets and want to present them in one report using a template.
The analysis per dataset could look like this:
child.Rmd
## Name of dataset
```{r calculate_stats}
summary(ds)
nrows <- nrow(ds)
```
The number of rows in the dataset is `r nrows`
The full report has this structure:
parent.Rmd
# Report
```{r import_all_datasets}
...import all datasets form csv...
ds.list <- c(ds1, ds2, ds3, ...)
```
for ds in ds.list
run child.Rmd with ds as a parameter
An additional requirement is that I can run the child.Rmd report alone with a specified parameter. The linked answer in comments below uses double curly braces ({{i}}) and knit_expand replaces it with i in the parent environment. This is unsatisfactory as it makes it a faff to call child.Rmd on its own.
Is it possible for the child to be a parametrised report and for the parent to pass the child the list of parameters.
I'm just attempting to do this now by trying:
child.Rmd
---
output: pdf_document
params:
ds: !r cars
name: "cars"
---
`r params$name`
=====
```{r}
summary(params$ds)
nrows <- nrow(params$ds)
```
The number of rows in the dataset is `r nrows`
And passing params to child within parent.Rmd

R inline markdown

I’m using R Markdown in RStudio to create a report that mixes Markdown and R output. I know how to use inline R expressions in the Markdown, but I’m wondering how to do the converse, i.e., use Markdown within the R code. I want to loop through a series of calculations and get Markdown headings for each one. I want headings for formatting purposes (e.g., bold titles etc) and also to be able to specify (sub)sections in the resulting PDF (which is a nice feature of the way RMarkdown handles # and ## etc).
I know I can do the following:
---
title: "test"
output: pdf_document
---
#Section 1
```{r, echo=FALSE}
print(1+1)
```
#Section 2
```{r, echo=FALSE}
print(2+2)
```
#Section 3
```{r, echo=FALSE}
print(3+3)
```
Which gives something looking (roughly) like this:
Section 1
## [1] 2
Section 2
## [1] 4
Section 3
## [1] 6
Is it possible to achieve the same output using something along the lines of this:
---
title: "test2"
output: pdf_document
---
```{r, echo=FALSE}
for (i in 1:3)
{
print(paste("#Section",i))
print(i+i)
}
```
As #scoa pointed out, you have to set the chunk option results='asis'. You should also place two \n both before and after your header.
---
title: "test"
output: pdf_document
---
```{r, echo=FALSE, results='asis'}
for (i in 1:3) {
cat(paste0("\n\n# Section", i, "\n\n"))
print(i+i)
cat("\n\n\\newpage")
}
```
As a more general answer, it could be useful to a look at the markdownreports package that parses markdown code (and output) from your R variables.

Creating summaries at the top of a knitr report that use variables that are defined later

Is there a standard way to include the computed values from variables early on in the written knitr report before those values are computed in the code itself? The purpose is to create an executive summary at the top of the report.
For example, something like this, where variable1 and variable2 are not defined until later:
---
title: "Untitled"
output: html_document
---
# Summary
The values from the analysis are `r variable1` and `r variable2`
## Section 1
In this section we compute some values. We find that the value of variable 1 is `r variable1`
```{r first code block}
variable1 <- cars[4, 2]
```
## Section 2
In this section we compute some more values. In this section we compute some values. We find that the value of variable 2 is `r variable2`
```{r second code block}
variable2 <- cars[5, 2]
```
A simple solution is to simply knit() the document twice from a fresh Rgui session.
The first time through, the inline R code will trigger some complaints about variables that can't be found, but the chunks will be evaluated, and the variables they return will be left in the global workspace. The second time through, the inline R code will find those variables and substitute in their values without complaint:
knit("eg.Rmd")
knit2html("eg.Rmd")
## RStudio users will need to explicitly set knit's environment, like so:
# knit("eg.Rmd", envir=.GlobalEnv)
# knit2html("eg.Rmd", envir=.GlobalEnv)
Note 1: In an earlier version of this answer, I had suggested doing knit(purl("eg.Rmd")); knit2html("eg.Rmd"). This had the (minor) advantage of not running the inline R code the first time through, but has the (potentially major) disadvantage of missing out on knitr caching capabilities.
Note 2 (for Rstudio users): RStudio necessitates an explicit envir=.GlobalEnv because, as documented here, it by default runs knit() in a separate process and environment. It default behavior aims to avoid touching anything in global environment, which means that the first run won't leave the needed variables lying around anywhere that the second run can find them.
Here is another approach, which uses brew + knit. The idea is to let knitr make a first pass on the document, and then running it through brew. You can automate this workflow by introducing the brew step as a document hook that is run after knitr is done with its magic. Note that you will have to use brew markup <%= variable %> to print values in place.
---
title: "Untitled"
output: html_document
---
# Summary
The values from the analysis are <%= variable1 %> and
<%= variable2 %>
## Section 1
In this section we compute some values. We find that the value of variable 1
is <%= variable1 %>
```{r first code block}
variable1 = cars[6, 2]
```
## Section 2
In this section we compute some more values. In this section we compute
some values. We find that the value of variable 2 is <%= variable2 %>
```{r second code block}
variable2 = cars[5, 2]
```
```{r cache = F}
require(knitr)
knit_hooks$set(document = function(x){
x1 = paste(x, collapse = '\n')
paste(capture.output(brew::brew(text = x1)), collapse = '\n')
})
```
This has become pretty easy using the ref.label chunk option. See below:
---
title: Report
output: html_document
---
```{r}
library(pixiedust)
options(pixiedust_print_method = "html")
```
### Executive Summary
```{r exec-summary, echo = FALSE, ref.label = c("model", "table")}
```
Now I can make reference to `fit` here, even though it isn't yet defined in the script. For example, a can get the slope for the `qsec` variable by calling `round(coef(fit)[2], 2)`, which yields 0.93.
Next, I want to show the full table of results. This is stored in the `fittab` object created in the `"table"` chunk.
```{r, echo = FALSE}
fittab
```
### Results
Then I need a chunk named `"model"` in which I define a model of some kind.
```{r model}
fit <- lm(mpg ~ qsec + wt, data = mtcars)
```
And lastly, I create the `"table"` chunk to generate `fittab`.
```{r table}
fittab <-
dust(fit) %>%
medley_model() %>%
medley_bw() %>%
sprinkle(pad = 4,
bg_pattern_by = "rows")
```
I work in knitr, and the following two-pass system works for me. I have two (invisible) code chunks, one at the top and one at the bottom. The one at the bottom saves the values of any variables I need to include in the text before they are actually computed in a file (statedata.R). The top chunk sets the variable values to something that stands out if they haven't been defined yet, and then (if it exists) it grabs the actual values from the stored file.
The script needs to be knit twice, as values will be available only after one pass through. Note that the second chunk erases the saved state file at the end of the second pass, so that any later changes to the script that affect the saved variables will have to be computed anew (so that we don't accidentally report old values from an earlier run of the script).
---
title: "Untitled"
output: html_document
---
```{r, echo=FALSE, results='hide'}
# grab saved computed values from earlier passes
if (!exists("variable1")) {
variable1 <- "UNDEFINED"
variable2 <- "UNDEFINED"
if (file.exists("statedata.R")) {
source("statedata.R")
}
}
# Summary
The values from the analysis are `r variable1` and `r variable2`
## Section 1
In this section we compute some values. We find that the value of variable 1 is `r variable1`
```{r first code block}
variable1 <- cars[4, 2]
```
## Section 2
In this section we compute some more values. In this section we compute some values. We find that the value of variable 2 is `r variable2`
```{r second code block}
variable2 <- cars[5, 2]
```
```{r save variables for summary,echo=FALSE,results='hide'}
if (!file.exists("statedata.R")) {
dump(c("variable1","variable2"), file="statedata.R")
} else {
file.remove("statedata.R")
}
```
Latex macros can solve this problem. See this answer to my related question.
\newcommand\body{
\section{Analysis}
<<>>=
x <- 2
#
Some text here
} % Finishes body
\section*{Executive Summary}
<<>>=
x
#
\body

Resources