quarto rmarkdown code block to only display certain lines - r

I have a .qmd / .rmd file that wants to show the output of block of code. The code block has a lot of lines at the beginning that I'd like to hide, in the example below I'd like the output to be the third line of code str(month) and output the result of str(month). I've attempted to edit the code block parameters, but it's giving me an error:
---
format:
html: default
---
```{r}
#| echo: c(3)
month <- "July"
str(month)
```
Error:
7: #| echo: c(3)
~~~
8: month <- "July"
x The value c(3) is string.
i The error happened in location echo.
rmarkdown support files suggest something like this might be possible

This does not work because you are using YAML syntax for chunk options as recommended with Quarto but #| echo: c(3) is not valid YAML. #| echo: 3 is.
You can use !expr within YAML field to parse R code if necessary. #| echo: !expr c(3) would work. It is explained here: https://quarto.org/docs/computations/r.html#chunk-options
However, know that knitr supports other way to specify chunk options:
Usual header where option needs to be valid R code
```{r, echo = c(3)}
#| echo: c(3)
month <- "July"
str(month)
```
And a multiline version of it, useful when having long option like fig.cap
```{r}
#| rmdworkflow,
#| echo = FALSE,
#| fig.cap = "A diagram illustrating how an R Markdown document
#| is converted to the final output document.",
#| out.width = "100%"
knitr::include_graphics("images/workflow.png", dpi = NA)
```
See the announced in blog post for more about this new syntax: https://yihui.org/en/2022/01/knitr-news/
This question has also been asked in Github - so more detailed answer there: https://github.com/quarto-dev/quarto-cli/issues/863

I don't know if I understood the question correctly. But you can choose to display only the code you want based on the index of the line inside specific chunk. Insert the number of index line you want to show inside the c() {r, echo = c()}
Your specific case
---
format:
html: default
---
```{r, echo = c(2)}
month <- "July"
str(month) # line 2
```
Other Example:
---
format:
html: default
---
```{r, echo = c(5,8)}
# Hide
month <- "July"
## Show code and output
str(month) # Line 5
## Show code and output
1+1 # Line 8
## Show just output
2+2
```

Related

An interactive learning widget for R using Quarto

The following Test.Rmd will produce an interactive learning widget for r using knitr (see the link).
---
title: "Example Document"
author: "Your name here"
output:
html_document:
self_contained: false
---
```{r, include = FALSE}
tutorial::go_interactive()
```
By default, `tutorial` will convert all R chunks.
```{r}
a <- 2
b <- 3
a + b
```
Edited
Wondering how to an get an interactive learning widget for r using quarto. Need help for YAML of .qmd, my attempt is
---
title: "Test"
author: "MYaseen208"
format:
html:
self_contained: false
---
```{r}
#| echo: false
#| include: false
tutorial::go_interactive()
```
```{r}
#| echo: false
1 + 1
```
You can add options to executable code like this
```{r}
#| echo: false
2 * 2
```
The `echo: false` option disables the printing of code (only output is displayed).
However, it throws the following error:
ERROR: Validation of YAML front matter failed.
ERROR: (line 5, columns 3--7) Field "html" has empty value but it must instead be an object
4: format:
5: html:
~
6: ---
ERROR: Render failed due to invalid YAML.
Another attempt which render but don't produce the required output:
---
title: "Test1"
author: "MYaseen208"
format:
html:
output-file: "Test1.html"
self-contained: false
---
To fix the error, you should use self-contained instead of self_contained in quarto like this:
---
title: "Test"
author: "MYaseen208"
format:
html:
self-contained: false
---
```{r}
#| echo: false
#| include: false
tutorial::go_interactive()
```
```{r}
#| echo: false
1 + 1
```
You can add options to executable code like this
```{r}
#| echo: false
2 * 2
```
The `echo: false` option disables the printing of code (only output is displayed).
Output:
I don't think the package is currently supported on Quarto, since the latest release of the package was in 2016. You might contact them about this.

Run an R Markdown based on interactive parameter choice

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:

Pass Params from loop to generate Dynamic Reports in Rmarkdown

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.

purl() within knit() duplicate label error

I am knitting a .Rmd file and want to have two outputs: the html and a purl'ed R script each time I run knit. This can be done with the following Rmd file:
---
title: "Purl MWE"
output: html_document
---
```{r}
## This chunk automatically generates a text .R version of this script when running within knitr.
input = knitr::current_input() # filename of input document
output = paste(tools::file_path_sans_ext(input), 'R', sep = '.')
knitr::purl(input,output,documentation=1,quiet=T)
```
```{r}
x=1
x
```
If you do not name the chunk, it works fine and you get html and .R output each time you run knit() (or click knit in RStudio).
However, if you name the chunk it fails. For example:
title: "Purl MWE"
output: html_document
---
```{r}
## This chunk automatically generates a text .R version of this script when running within knitr.
input = knitr::current_input() # filename of input document
output = paste(tools::file_path_sans_ext(input), 'R', sep = '.')
knitr::purl(input,output,documentation=1,quiet=T)
```
```{r test}
x=1
x
```
It fails with:
Quitting from lines 7-14 (Purl.Rmd)
Error in parse_block(g[-1], g[1], params.src) : duplicate label 'test'
Calls: <Anonymous> ... process_file -> split_file -> lapply -> FUN -> parse_block
Execution halted
If you comment out the purl() call, it will work with the named chunk. So there is something about how the purl() call is also naming chunks which causes knit() to think there are duplicate chunk names even when there are no duplicates.
Is there a way to include a purl() command inside a .Rmd file so both outputs (html and R) are produced? Or is there a better way to do this? My ultimate goal is to use the new rmarkdown::render_site() to build a website that updates the HTML and R output each time the site is compiled.
You can allow duplicate labels by including options(knitr.duplicate.label = 'allow') within the file as follows:
title: "Purl MWE"
output: html_document
---
```{r GlobalOptions}
options(knitr.duplicate.label = 'allow')
```
```{r}
## This chunk automatically generates a text .R version of this script when running within knitr.
input = knitr::current_input() # filename of input document
output = paste(tools::file_path_sans_ext(input), 'R', sep = '.')
knitr::purl(input,output,documentation=1,quiet=T)
```
```{r test}
x=1
x
```
This code isn't documented on the knitr website, but you can keep track with the latest changes direct from Github: https://github.com/yihui/knitr/blob/master/NEWS.md
A related approach to #ruaridhw solution would be to wrap the knitr::purl() in callr::r(). See function below that saves the R chunks from a specified R markdown file to a temporary .R file:
# RMD to local R temp file
# inspiration: https://gist.github.com/noamross/a549ee50e8a4fd68b8b1
rmd_chunks_to_r_temp <- function(file){
temp <- tempfile(fileext=".R")
# needed callr so can use when knitting -- else can bump into "duplicate chunk
# label" errors when running when knitting
callr::r(function(file, temp){
knitr::purl(file, output = temp)
},
args = list(file, temp))
}
This function also exists in funspotr:::rmd_chunks_to_r_temp() at brshallo/funspotr.
You can avoid this error with a bash chunk that calls purl in a separate R session. That way there's no need to allow duplicate labels.
An example use case is an Rmd file where the code is run (and not echo'd) throughout the report and then all the code chunks are shown with chunks names and code comments in an Appendix. If you don't require that additional functionality then you would only need up until the bash chunk.
The idea is that report_end signifies where to stop purl such that the appendix code isn't considered "report code". Then read_chunk reads the entire R file into one code chunk which can then be echo'd with syntax highlighting if required.
---
title: "Purl MWE"
output: html_document
---
These code chunks are used in the background of the report however
their source is not shown until the Appendix.
```{r test1, echo=FALSE}
x <- 1
x
```
```{r test2, echo=FALSE}
x <- x + 1
x
```
```{r test3, echo=FALSE}
x <- x + 1
x
```
# Appendix
```{r, eval=TRUE}
report_end <- "^# Appendix"
temp <- tempfile(fileext = ".R")
Sys.setenv(PURL_IN = shQuote("this_file.Rmd"), # eg. knitr::current_input()
PURL_OUT = shQuote(temp),
PURL_END = shQuote(report_end))
```
```{bash, include=FALSE}
Rscript -e "lines <- readLines($PURL_IN, warn = FALSE)" \
-e "knitr::purl(text = lines[1:grep($PURL_END, lines)], output = $PURL_OUT, documentation = 1L)"
```
```{r, include=FALSE}
knitr::read_chunk(temp, labels = "appendix")
unlink(temp)
```
```{r appendix, eval=FALSE, echo=TRUE}
```

How to include a header based on a condition in knitr

I have a header followed by a code chunk in an Rmd file. I only want to include this header and the chunk followed by it, if a condition is met. I know how to do that with the chunk, since it's in the body of the code, but how do I do the former?
```{r}
print_option <- TRUE
```
## My header
```{r}
if(print_option==TRUE) {
print (x)
}
```
The chunk option eval and asis_output() provide a simple solution.
Assuming that print_option is a boolean indicating whether to show the header (and whether to execute other code like print(1:10) in chunk example1):
```{r setup}
library(knitr)
print_option <- TRUE
```
```{r, eval = print_option}
asis_output("## My header\\n") # Header that is only shown if print_option == TRUE
print(1:10) # Other stuff that is only executed if print_option == TRUE
```
Text that is shown regardless of `print_option`.
```{r setup2}
print_option <- FALSE
```
Now `print_option` is `FALSE`. Thus, the second header is not shown.
```{r, eval = print_option}
asis_out("## Second header\\n")
```
Output:
For longer conditional outputs (of text/markdown, without embedded R code) the engine asis can be helpful, see this answer (it's long, but the solution at the end is very concise).
Addendum
Why is ## `r Title` with Title set to "My header" or "" as suggested in this answer a bad idea? Because it creates an "empty header" in the second case. This header is not visible in the rendered HTML/markdown output, but it is still there. See the following example:
```{r, echo = FALSE}
title <- ""
```
## `r title`
This generates the following markdown ...
##
... and HTML:
<h2></h2>
Besids being semantically nonsense it might lead to layout issues (depending on the style sheet) and disrupts the document outline.
I figured it out :)
```{r, echo=FALSE, include=FALSE}
x<- FALSE
if ( x ) {
Title <- "My header"
} else {Title=""}
```
## `r Title`
```{r, echo=FALSE}
if(x) {
print(1:10)
}
```

Resources