For some reason, I need to use knitr::knit()
on an Rmarkdown file, the input file (file1.Rmd
), to create another Rmarkdown file, the output file (file2.Rmd
).
knitr::knit("file1.Rmd", output = "file2.Rmd")
Naturally, the output file will include the results of some evaluated chunks in the input file. However, I would like to keep some chunks "as is" in the output file, "as is" in the sense that if I use knir::knit()
again on the output file, those chunks can be evaluated as usual.
For example, these are two chunks in the input file.
```{r}
x <- 1
x
```
```
{r eval=FALSE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
In the output file, this is the result for the first chunk:
``` r
x <- 1
x
```
```
## [1] 1
```
With the code above, this is the result for the second chunk:
``` r
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
However, I would like to keep the second chunk in its original form, that is:
```
{r eval=FALSE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
How can I do this with Rmarkdown?
(Edit)
I don't know whether I am asking for "too much" from Rmarkdown. If possible, I would even like to have this, automatically, in the output file (`file2.Rmd`), with `eval=TRUE`:
```
{r eval=TRUE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
Whether this chunk appears in exactly the same way in the input file (`file1.Rmd`) is optional. I just want to do this automatically, without the need to edit the output file.
I indeed have tried `"asis"`. This is in the input file:
```
{r eval=FALSE, results="asis"}
{r eval=TRUE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
This is in the output file:
``` r
{r eval=TRUE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```
The result is close to what I want. However, I still need to manually edit the first two lines to become this one:
```
{r eval=TRUE, echo=TRUE}
```
The simplest way to do this is to write a function that just echoes its input into the output, wrapping in markup to look like a code chunk. For example,
---
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
echoinput <- function(input) cat("```", input, "\n```\n", sep="")
```
```{r echo=FALSE, results='asis'}
echoinput("{r eval=TRUE, echo=TRUE}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z")
```
This adds the backticks at the beginning and end of the string it is writing. RStudio or other editors will see the code as a string, not as code, so you won't be able to run it in the editor. If you want to do that, your echoinput()
function will need to be more sophisticated.
Here's an ugly version of the sophisticated approach. It sets a hook on the eval
chunk option, which saves the code into a global variable, then replaces it with code that just echos the content of that variable. I don't recommend using this unmodified; at a minimum, you should work out ways to avoid using the global variable. I'll leave that up to you to do.
---
title: "Untitled"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
echocode <- function(options) {
if (identical(options$eval, "echocode")) {
code_to_echo <<- paste0(
"```{r echo=", options$echo, ", eval=TRUE}\n",
paste(options$code, collapse="\n"),
"\n```\n")
options$code <- "cat(code_to_echo)"
options$echo <- FALSE
options$eval <- TRUE
options$results <- "asis"
options
} else
options
}
```
```{r eval="echocode"}
# This chunk should be in the output as a chunk
y <- 1
z <- 2
y + z
```