RMarkdown Using comments to make sections optional - r

Is it possible to have entire sections programmatically commented out in RMarkdown. For example, say I have a section of my report :
### 2.1. Heading
Blah blah blah my description, with `r variables` and other stuff.
#### Table 2.1.1. Sub heading
```{r table_2_1_1}
kable_2_1_1
```
Now based on a boolean in the code, I want to completely comment out that whole section. I've tried putting r variables into the report like "< !--" & "-->" but that does not work.

You can pass a boolean value to eval in your rmd chunk to conditionally knit different blocks of rmarkdown code:
---
title: "Untitled"
author: "Matt"
date: "12/21/2021"
output: html_document
---
```{r setup, include=FALSE}
library(knitr)
knitr::opts_chunk$set(echo = TRUE)
should_i_evaluate <- F
```
```{r header, eval = should_i_evaluate}
asis_output("# My Header")
```
```{asis, echo = should_i_evaluate}
Blah blah blah my description, with `r names(mtcars[1:3])` and other stuff.
```
```{r cars, eval = should_i_evaluate}
summary(mtcars)
```
When should_i_evaluate is TRUE:
When should_i_evaluate is FALSE:

Related

Insert Pagebreak for Output after Code Chunk

I have a .Rmd file which I am converting to PDF. For layout reasons, I want to display the generated output plot of my code chunk on the next page even though it would just fit in underneath.
Normally with text etc. one would use
\pagebreak
But how can I signalize the code chunk that it should display its output on the next page?
Thanks for helping!
You can write a knitr hook to set up a chunk option to do this.
So here I have modified the source chunk hook and created a chunk option next_page which, if TRUE, the output of that chunk will be on the next page.
---
title: "Chunk Output in Next page"
output: pdf_document
date: "2022-11-25"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r, include=FALSE}
library(knitr)
default_source_hook <- knit_hooks$get('source')
knit_hooks$set(
source = function(x, options) {
if(isTRUE(options$next_page)) {
paste0(default_source_hook(x, options),
"\n\n\\newpage\n\n")
} else {
default_source_hook(x, options)
}
}
)
```
```{r, next_page=TRUE}
plot(mpg ~ disp, data = mtcars)
```
I would recommend you to save the output in the file (png/jpeg/pdf) and then load it with the markdown or knitr.
Such solution gives you a full control.
Automatic
I found alternative solution in rmarkdown-cookbook.
We generate a plot in this code chunk but do not show it:
```{r cars-plot, dev='png', fig.show='hide'}
plot(cars)
```
\newpage
![A nice plot.](\`r knitr::fig_chunk('cars-plot', 'png')\`)
Manual
```{r}
png("NAME.png")
# your code to generate plot
dev.off()
```
then load image with
![LABEL](PATH/NAME.png) or with
```{r echo=FALSE, out.width='100%', ...}
knitr::include_graphics('PATH/NAME.png')
```

How can I change the placement of the caption and modify the color of cross-referencing in the R markdown generated pdf document?

---
title: "Annual Report"
author: "Xyz"
date: "`r format(Sys.time(),'%d %B, %Y')`"
output:
bookdown::pdf_document2:
extra_dependencies: ["float"]
number_sections: false
toc: false
---
```{r, echo = FALSE}
library(ggplot2)
data(mtcars)
names(mtcars)
```
### Heading 1
```{r figure-1,echo=FALSE, fig.cap = "Sample Graph 1"}
ggplot(mtcars,aes(x=mpg,y=hp))+
geom_point()+
theme_classic()
```
To see another graph, please see figure \#ref(fig:figure-2)
\newpage
### Heading 2
```{r figure-2,echo=FALSE, fig.cap = "Sample Graph 2"}
ggplot(mtcars,aes(x=mpg,y=carb))+
geom_point()+
theme_classic()
```
To see another graph, please see figure \#ref(fig:figure-1)
I have tried to enclose #ref in the \textcolor{}{}, but Latex removes the cross-referencing and only shows #ref(fig:figure-1) in the knitted pdf document.
Moreover, I want to put the caption at the top of the figure instead of being at the bottom. I looked over Stackoverflow and users are recommending to use floatrow package to control the placement of caption, but I can't use floatrow with float package. I am using float package in my document to control for extra spaces in my document by using the following code written in Latex:
\usepackage{float}
\let\origfigure\figure
\let\endorigfigure\endfigure
\renewenvironment{figure}[1][2] {
\expandafter\origfigure\expandafter[H]
} {
\endorigfigure
}
Please help me out in sorting out these issues :)
I was able to figure out the solution to both of the problems mentioned in my question. I am sharing my solution to both problems for the other learners below:
Change the Cross-Reference Color
We cannot use Latex \textcolor{}{} to change the color of the cross-referencing in R Markdown. My thinking is R Markdown confuses multiple Latex commands with simple words while knitting the document.
Xie et al. (2020) has addressed this problem by creating a lua filter. I opened "The Notepad" and copied the code given in the book. And I saved the file as color-text.lua. The code is given below for the reader's convenience:
Span = function(el)
color = el.attributes['color']
-- if no color attribute, return unchange
if color == nil then return el end
-- transform to <span style="color: red;"></span>
if FORMAT:match 'html' then
-- remove color attributes
el.attributes['color'] = nil
-- use style attribute instead
el.attributes['style'] = 'color: ' .. color .. ';'
-- return full span element
return el
elseif FORMAT:match 'latex' then
-- remove color attributes
el.attributes['color'] = nil
-- encapsulate in latex code
table.insert(
el.content, 1,
pandoc.RawInline('latex', '\\textcolor{'..color..'}{')
)
table.insert(
el.content,
pandoc.RawInline('latex', '}')
)
-- returns only span content
return el.content
else
-- for other format return unchanged
return el
end
end
Once the file is saved, we need to incorporate color-text.lua in the YAML header of our required document. We will incorporate the lua file by modifying YAML header:
---
title: "Annual Report"
author: "Xyz"
date: "`r format(Sys.time(),'%d %B, %Y')`"
output:
bookdown::pdf_document2:
pandoc_args: ["--lua-filter=color-text.lua"]
number_sections: false
toc: false
---
After modifying the YAML header, we can change the font color of cross-referenced text by doing it the following way:
To see another graph, please see figure [\#ref(fig:figure-2)]{color="blue"}
We need to write the cross-referenced text within square brackets followed by color argument within {}.
Changing the placement of the caption and controlling for extra whitespaces
If we want to change the placement of the caption and control for extra white space in our pdf document, we need to include the following lines in our .tex file
\usepackage{floatrow}
\usepackage[onehalfspacing]{setspace}
\floatsetup[figure]{capposition=top}
\floatplacement{figure}{H}
After saving the above tex file as caption_control.tex, we will include it in our YAML header:
---
title: "Annual Report"
author: "Xyz"
date: "`r format(Sys.time(),'%d %B, %Y')`"
output:
bookdown::pdf_document2:
pandoc_args: ["--lua-filter=color-text.lua"]
number_sections: false
toc: false
includes:
in_header: caption.control.tex
---

Toggle chunk output using "details" HTML tag

I'm writing some tutorials using blogdown. For a pedagogical reason, I want my students to think before seeing the solution. Here's my current code.
Original
---
title: "Toggle Chuck Output Using details Tag"
output: html_document
---
```{r calc, prompt=TRUE, eval=FALSE}
90 + 30
```
<details>
<summary>Toggle output</summary>
```{r, ref.label='calc', echo=FALSE, prompt=TRUE}
```
</details>
Here's my attempt:
To avoid repeatedly writing the HTML tags, I think I need to define a function similar to ...
togglable <- function(label, summary = "Toggle output"){
cat('<details>')
cat(' <summary>', summary, '</summary>', sep = '')
# Code to print output using 'ref.label' should go here.
# The following doesn't work.
knitr::knit_print(knitr:::knit_code$get(label))
cat('</details>')
}
.... then replace the <detals>...</details> block with a R code chunk similar to the following:
Use case 1 (better)
```{r usecase1, echo=FALSE, results='asis'}
togglable(label = "calc")
```
I tried to make it work, but in vain.
One more thing. If possible, I'd like this togglable() function to override the chunk options so that I don't even need to write echo=FALSE, results='asis', because the following chunk would look nicer.
Use case 2 (best)
```{r usecase2}
togglable(label = "calc")
```
In summary, I would like to ask the following questions.
How can I define this togglable() function so that it behaves in the same way as the original <detals>...</details> block?
Is it possible that this function overrides the options (echo and results in particular) for the chunk where this function is called? If yes, how?
Alternatively, is there any other idea how to produce the result of the original code without repeatedly writing the HTML tags?
Thank you very much!
This can be done by a combination of the chunk option ref.label (to reuse chunks), a chunk hook (to print the <details> tag) and a option hook (to change the chunk options when displaying the results.
---
title: "Toggle Chuck Output Using details Tag"
output: html_document
---
```{r setup, include=FALSE}
library(knitr)
knit_hooks$set(showDetails = function(before, options, envir) {
if (before) {
return("<details>\n")
} else {
return("\n</details>")
}
})
opts_hooks$set(showDetails = function(options) {
if(options$showDetails) {
options$echo = FALSE
options$results = "asis"
}
return(options)
})
```
```{r calc, prompt=TRUE, eval=FALSE}
90 + 30
```
```{r, ref.label="calc", showDetails = TRUE}
```
How it works:
The chunk hook is executed before and after each chunk where the option showDetails is not NULL. It prints (returns) the respective HTML.
The option hook adjusts the other options (echo and results) for each chunk there showDetails is TRUE.
The code could be further improved by globally setting the options of the calc chunk, such that you do not have to repeat them for all other "show code only" chunks: add opts_chunk$set(prompt = TRUE, eval = FALSE) to the setup chunk and options$eval = TRUE to the option hook.
Besides, if you want <detail> tags by default whenever using ref.label, you could use ref.label as option hook:
```{r setup, include=FALSE}
library(knitr)
opts_chunk$set(prompt = TRUE, eval = FALSE)
knit_hooks$set(showDetails = function(before, options, envir) {
if (before) {
return("<details>\n")
} else {
return("\n</details>")
}
})
opts_hooks$set(ref.label = function(options) {
options$echo = FALSE
options$results = "asis"
options$eval = TRUE
options$showDetails = TRUE
return(options)
})
```
```{r calc}
90 + 30
```
```{r, ref.label="calc"}
```

Rmarkdown child documents do not detect their `params`

I have a master Rmarkdown document into which I am including my individual chapters using knitr's child option. Each chapter makes use of rmarkdown parameters in its own YAML.
Each chapter compiles well individually, but when put in this master document, I get the error
object: 'params' not found
I believe it is because when the child is knitted, knitr does not read the parameters in the YAML (which is an rmarkdown feature, not a knitr feature).
Is there some way I can make these available to knitr? Is there an "rmarkdown"-way of putting in child documents?
---
title: My thesis
---
blah blah.
# Introduction
```{r child='01-introduction.rmd'}
```
# Mathematical background
```{r child='02-mathsy-maths.rmd'}
```
Example 01-introduction.rmd
---
title: Introduction
params:
dataset: ABC
---
As I understand knitr, when you knit a child document, this document is evaluated in the context (ie environment) of the parent document.
So, I see 4 solutions.
Set the params in the main document
With this solution, params are controlled inside the YAML front-matter of the main document. I think it is the natural solution.
---
title: My thesis
params:
dataset: ABC
---
blah blah.
# Introduction
```{r child='01-introduction.rmd'}
```
# Mathematical background
```{r child='02-mathsy-maths.rmd'}
```
Assign the params in the global environment
With this solution, params are controlled with R code inside the main document.
---
title: My thesis
---
blah blah.
# Introduction
```{r set-params, include=FALSE}
params <- list(dataset = "ABC")
```
```{r child='01-introduction.rmd'}
```
# Mathematical background
```{r child='02-mathsy-maths.rmd'}
```
Retrieve params of the child document
With this solution, params are controlled inside each child document. It is a variant of the previous solution.
In the main document, child document's params are read using knitr::knit_params() and then assigned in the global environment.
---
title: My thesis
---
blah blah.
```{r def-assign-params, include=FALSE}
assign_params <- function(file) {
text <- readLines(file)
knit_params <- knitr::knit_params(text)
params <<- purrr::map(knit_params, "value")
}
```
# Introduction
```{r, include=FALSE}
assign_params('01-introduction.rmd')
```
```{r child='01-introduction.rmd'}
```
# Mathematical background
```{r child='02-mathsy-maths.rmd'}
```
Use a (hacky) hook to assign params temporarily
Here, I define a hook for a new use.params chunk option: this solution extends the previous one. When use.params=TRUE is used, this hook is run for each chunk of the child document.
Note that with this solution, you cannot use params in inline code.
---
title: "Main document"
---
```{r hook-def, include=FALSE}
params_cache <- new.env(parent = emptyenv())
knitr::knit_hooks$set(use.params = function(before, options, envir) {
if (before && options$use.params) {
if (exists("params", envir = envir)) {
params_cache$params <- envir$params
}
text <- readLines(knitr::current_input(dir = TRUE))
knit_params <- knitr::knit_params(text)
envir$params <- purrr::map(knit_params, "value")
}
if (!before && options$use.params) {
if (exists("params", envir = params_cache)) {
envir$params <- params_cache$params
rm("params", envir = params_cache)
} else {
rm("params", envir = envir)
}
}
})
```
blah blah.
# Introduction
```{r child='01-introduction.rmd', use.params=TRUE}
```
# Mathematical background
```{r child='02-mathsy-maths.rmd', use.params=TRUE}
```

kable_as_image knitr/kableextra rmarkdown

I am trying to use the function kable_as_image, which from my understanding will save the table as a image. My results though is not a table, dont know if I am doing something wrong as I cant find an example.
---
title: "Untitled"
author: "Test"
date: '2017-11-29'
output: pdf_document
---
```{r}
library(knitr)
library(kableExtra)
```
```{r}
kable_as_image(kable(head(iris)), filename = "~/Documents/.../.../pic")
```
#warning: kpathsea: gloss-$mainlang$.ldf: Unrecognized variable construct `$.'.
What my "picture" looks like:
Now I feel like kable_as_image is a somehow misleading name for the function. As explained in the doc, as least right now, it only works for latex tables, try kable_as_image(kable(..., format = "latex", booktabs = T), filename = "pic").

Resources