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.
Related
This question is similar, but not identical to this one.
Basically, I have a number of tables that I would like to show in tabsets using DT::datatable(). Unfortunately, I can't figure out how.
The following code works, but I need to manually type all the code:
---
title: "Untitled"
format: html
---
```{r}
library(DT)
```
::: {.panel-tabset}
### table no. 1
```{r}
#| results: asis
datatable(mtcars)
```
### table no. 2
```{r}
#| results: asis
datatable(mtcars)
```
:::
The following works, but instead of datatable() uses a simple markdown table from pander which does not give the desired effect.
---
title: "Untitled"
format: html
---
```{r}
library(pander)
```
::: {.panel-tabset}
```{r}
#| results: asis
for(i in 1:2) {
cat(sprintf("\n### table no. %d\n\n", i))
cat(pander(mtcars))
}
```
:::
The following code does not work, and I don't know how to make it work:
---
title: "Untitled"
format: html
---
```{r}
library(DT)
```
::: {.panel-tabset}
```{r}
#| results: asis
for(i in 1:2) {
cat(sprintf("\n### table no. %d\n\n", i))
print(datatable(mtcars))
}
```
:::
This is a known issue in the context of RMarkdown. But as it turns out the solution for RMarkdown also works for Quarto.
Following this answer related to the same issue in RMarkdown [Discalimer: The answer is from me] you could achieve your desired result by first making sure that the javascript dependencies needed for DT are included in your document and by wrapping the datatable call inside htmltools::tagList:
---
title: "Untitled"
format: html
---
```{r}
library(DT)
```
```{r, include=FALSE}
# Init Step to make sure that the dependencies are loaded
htmltools::tagList(datatable(mtcars))
```
::: {.panel-tabset}
```{r}
#| results: asis
for(i in 1:2) {
cat(sprintf("\n### table no. %d\n\n", i))
print(htmltools::tagList(datatable(mtcars)))
}
```
:::
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")
```
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.
Im new to Rmarkdown and I would like to create dynamic reports where every report section is generated from a template (child) document. Each section will then start with a newpage in the rendered pdf.
My approach is currently based on this post which shows how to generate dynamically text in the child (which works), however I am not able to transfer the contents of the loop into a R-Codeblock, probably because the params are not well defined in the way that I tried to do it.
This is how my parent document looks like:
---
title: "Dynamic RMarkdown"
output: pdf_document
---
```{r setup, include=FALSE}
library("knitr")
options(knitr.duplicate.label = "allow")
```
# Automate Chunks of Analysis in R Markdown
Blahblah Blabla
\newpage
```{r run-numeric-md, include=FALSE}
out = NULL
for (i in as.character(unique(iris$Species))) {
out = c(out, knit_expand('template.Rmd'))
params <- list(species = i)
}
```
`r paste(knit(text = out), collapse = '\n')`
and this is how the child looks like
---
title: "template"
output: html_document
params:
species: NA
---
# This is the reporting section of Species {{i}}
This is a plot of Sepal length and width based on species {{i}}.
```{r plot2}
paste(params$species)
# plot doesnt work work
# plot(iris$Sepal.Length[iris$Species=={{i}}],
# iris$Sepal.Width[iris$Species=={{i}}]
# )
```
\newpage
To my understanding the parameter that is actually passed is the last species from the dataset generated in the loop but I'm not sure why the plot would't work then. Can anybody help me out on how to fix this issue?
Ok. No need to go through params. The solution was simply to put i between brackets AND parenthesis in the child-document.
Parent:
---
title: "Dynamic RMarkdown"
output: pdf_document
---
```{r setup, include=FALSE}
library("knitr")
options(knitr.duplicate.label = "allow")
```
# Automate Chunks of Analysis in R Markdown
Blahblah Blahblah Main text before individual sections
\newpage
```{r run-numeric-md, include=FALSE}
out = NULL
for (i in as.character(unique(iris$Species))) {
out = c(out, knit_expand('template.Rmd'))
}
```
`r paste(knit(text = out), collapse = '\n')`
Child
---
title: "template"
output: html_document
---
# This is the reporting page of Species {{i}}
This is a plot of Sepal length and width based on species {{i}}.
```{r plot2}
paste("This will be a plot of Sepal Length and Witdh from", '{{i}}')
plot(iris$Sepal.Length[iris$Species=='{{i}}'],
iris$Sepal.Width[iris$Species=='{{i}}']
)
```
\newpage
Original solution found here.
Following this and this stackoverflow-questions, I tried to use knit-child inside a loop, containing a variable-defined title.
Instead of the variables (e.g. A, B, C) as title, I get them with # still attached (# A, # B, # C)
Parent:
---
title: "Untitled"
output: html_document
---
```{r,include=FALSE}
library(knitr)
```
```{r,echo=FALSE}
titles<-LETTERS[1:3]
```
```{r,include=FALSE,echo=FALSE}
out = NULL
for (i in titles){
out = c(out, knit_child('Child.Rmd'))
}
```
`r paste(out, collapse='\n')`
Child:
---
title: "Untitled"
output: html_document
---
```{r,echo=FALSE,results='asis'}
cat("\n\n # ", i,"\n")
```
```{r,echo=FALSE,results='asis'}
cat("\n\n This text is about ", i,"\n")
```
Output:
While I would prefer:
The # character only indicates a heading in markdown if it is the first character of the line.
cat("\n\n # ", i,"\n") produces two new lines, then one space and then the #. Remove the whitespace to fix the issue:
cat("\n\n# ", i,"\n")
Consider using pandoc.headerinstead of Cat.
i = 1
pander::pandoc.header(i, level = 1)
> # 1
pander::pandoc.header(paste0("Subheading ", i), level = 3)
> ### Subheading 1
I recommend using the knit_expand function.
You create your Child.Rmd as
# {{current_title}}
This text is about {{current_title}}
Remember that `current_title` is a literal string, so
if you want use it in code then must be quoted:
<!-- Use `current_title` in chunk name to avoid duplicated labels -->
```{r {{current_title}}}
data.frame({{current_title}} = "{{current_title}}")
```
Then your main document shoud looks like this:
---
title: "Untitled"
output: html_document
---
```{r,include=FALSE}
library(knitr)
```
```{r,echo=FALSE}
titles<-LETTERS[1:3]
```
```{r,include=FALSE,echo=FALSE}
expanded_child <- lapply(
titles
,function(xx) knit_expand("Child.Rmd", current_title = xx)
)
parsed_child <- knit_child(text = unlist(expanded_child))
```
`r parsed_child`
Results: