Custom language engine on Knitr - r

I have added a custom language engine on Knitr according the documentation.
require(knitr)
knit_engines$set(upper = function(options) {
code <- paste(options$code, collapse = "\n")
if (options$eval)
toupper(code) else code
})
And when I add text a following command to Rmd-file I can run a current chunk in RStudio.
```{upper}
Hello, **knitr** engines!
```.
HELLO, KNITR ENGINES!
But If I try to Knit a whole file to a html-page I can't see the result of chunked code. And I will get the following warning message on R Markdown tab.
Warning message:
In get_engine(options$engine) :
Unknown language engine 'upper' (must be registered via knit_engines$set()).
So how can I register the engine so that the program will see it later on?

---
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
knitr::knit_engines$set(upper = function(options) {
code <- paste(options$code, collapse = "\n")
if (options$eval)
toupper(code) else code
})
```
```{upper}
Hello, **knitr** engines!
```

Related

using params from YAML header with a shiny runtime Rmd

I would like to use params to pass settings for a shiny app. Consider the following document, which just prints a message when the checkbox is changed. I would like the message to be configuable using params in the yaml header.
However, it seems this fails as params seems to be only available when the document is rendered (notice that it correctly prints the message in the document itself). Is this correct? Is there any way of reading params at runtime? Is this documented anywhere?
Document is below:
---
title: "Test"
output: html_document
runtime: shiny
params:
message: "hi"
---
Can see this: `r params$message`
```{r eruptions, echo=FALSE}
shiny::checkboxInput("cb","Checkbox")
```
```{r, echo=FALSE}
observeEvent(input$cb, {
# This works
message("clicked")
# This fails:
# Error in message(params$message) : object 'params' not found
try(message(params$message))
})
```
This works by setting params to a non-local variable:
---
title: "Test"
output: html_document
runtime: shiny
params:
message: "hi"
---
```{r}
params <<- params
```
......

How to use if else statement in r chunk options to replace missing image with default image

title: File Reading
output: html_document
params:
user1: "C:/Users/myDir/Desktop/apples.jpeg"
user2: "C:/Users/myDir/Desktop/oranges.jpeg"
Lets say I have the following file paths set in params in a Rmardown file. Now I set a separate chunk for each file as follows:
```{r}
image_read(params$user1)
```
```{r}
image_read(params$user2)
```
Now lets say I want to knit the document but the path I have specified for user2 is not available. So I updated my chunks and added the following so if path is not available or correct, the chunk is not evaluated.
```{r, eval = file.exists(params$user2)}
image_read(params$user2)
What I want to do is to somehow specify if file does not exist then upload another image from a default path that I have specified in a separate chunk at the top of my file
```{r}
default_image <- "C:/Users/myDir/Desktop/default.jpeg"
```
So essentially whenever a file path is missing, I want to replace it with this default image. Any help would be appreciated
In this case a simple if-else statement would solve it. If you are going to run it multiple times it might be worth it packing it into a function.
---
title: "test conditional chunks"
output: html_document
params:
user1: "C:/Users/blah/Desktop/Discrete-event-simulation-concepts.png"
user2: "C:/Users/blah/Desktop/Discrete-event-simulation-concepts5.png"
default: "path_to_default"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
```{r}
library(magick)
```
```{r}
# basic example
if (file.exists(params$user1)) {
image_read(params$user1)
} else {
image_read(params$default)
}
```
```{r}
# packing into a function
image_read_with_default <- function(path, ...) {
if (file.exists(params$user1)) {
img <- magick::image_read(params$user1, ...)
} else {
img <- magick::image_read(params$default, ...)
}
return(img)
}
```
```{r}
image_read_with_default(params$user1)
```

Can you call/render a parameterized rmd report within another parameterized rmd report - rmarkdown

I'm wondering if it is actually possible to call/render a parameterized report from within another parameterized report?
I found [this][1] but it doesn't seem to come up with a solution.
Below is a minimal example where main-report.rmd tries to call/render sub-report-1.rmd . Both reports have the same params in the YAML header.
library(here)
sub-report-1.rmd
---
title: "Secondary report to run"
output: html_document
params:
country: "Canada"
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
paste0("Hello ", params$country)
```
main-report.rmd
---
title: "Main report"
output: html_document
params:
country: "France"
---
```{r run1, include=FALSE}
rmarkdown::render(here::here("rmd", "sub-report-1.rmd"),
output_format = "html_document",
output_file="report1.html",
params = list(country=params$country))
```
I get the following error:
Error: params object already exists in the knit environment so can't
be overwritten by rend param. Execution halted.
The solution is to use another parameter in the render function: envir = new.env(). The problem is that object params is already used.
rmarkdown::render(here::here("rmd", "sub-report-1.rmd"),
output_format = "html_document",
output_file="report1.html",
params = list(country=params$country),
envir = new.env())

Chunk option class.output is not working on Error Message

I am preparing a tutorial for a course and I want to change the colour of the error to be red. I am using BookDown and gitbook as my output format. But I found that the option class.output is not working. I want to add a class to the output for the error message I get. How can I do that? You can use this as an example:
---
title: "Test Book"
author: "therimalaya"
site: bookdown::bookdown_site
output: bookdown::gitbook
---
# Hello World
```{r, error = TRUE, class.output="red"}
rnorm(-10)
```
This works if there is no error.
class.output is not applied to errors (see here).
Following this answer, I suggest you to use an error hook:
```{r error-hook, echo=FALSE}
knitr::knit_hooks$set(error = function(x, options) {
paste0(
"```{",
ifelse(is.null(options$class.error),
"",
paste0(" .", gsub(" ", " .", options$class.error))
),
"}\n",
x,
"\n```"
)
})
```
Now, you can use a "new" class.error option in your chunk.
```{r, error = TRUE, class.error="red"}
rnorm(-10)
```
Feel free to open a feature request here.
The ability to use custom CSS classes for errors, warnings, and messages was just added to knitr, so you will be able to use the following syntax.
```{r error = TRUE, class.error = "bg-danger text-danger"}
rnorm(-10)
```
Here I'm using Bootstrap classes, but you can pass any class(es) you need to class.error. The chunk options class.message and class.warning also work. Note that class.output is applied only to standard code outputs.

Can a custom knit_hooks set options before and after R chunk?

I would like to specify text (specifically a div tag) before and after some R code in a Rmd file using github_document. I can't seem to get both the before and after to work.
For example knitting the following:
---
title: "Untitled"
output: github_document
---
```{r setup, include=FALSE}
library(knitr)
knit_hooks$set(toggle = function(before, options, envir) {
if(options$toggle){
if(before) {
print('<div id="hideMe">')
} else {
print("</div>")
}
}
})
```
## GitHub Documents
```{r pressure, echo=TRUE, toggle=TRUE}
# Here's some
```
Produces:
Untitled
================
GitHub Documents
----------------
``` r
# Here's some
```
If I delete the else part:
---
title: "Untitled"
output: github_document
---
```{r setup, include=FALSE}
library(knitr)
knit_hooks$set(toggle = function(before, options, envir) {
if(options$toggle){
if(before) {
print('<div id="hideMe">')
}
}
})
```
## GitHub Documents
```{r pressure, echo=TRUE, toggle=TRUE}
# Here's some
```
It works as expected, and I get the before section:
Untitled
================
GitHub Documents
----------------
<div id="hideMe">
``` r
# Here's some
```
If I use !before in the if statement, the trailing </div> shows up. But I have been unable to get both the leading and trailing sections to show up. Any suggestions to get both before and after text to show up?
Don't print in chunk hooks, return the text that is to be added to the document:
In knitr, hooks can also be used to insert texts into the output. To do this, the hook function must return a character result. [Source]
The most likely explanation for the behavior you observed is that in R, "if returns the value of the expression evaluated" (see ?Control section "Value").

Resources