Conditional 'Echo' (Or Eval or Include) in Rmarkdown Chunks

Conditional `echo` (or eval or include) in rmarkdown chunks

knitr options can be stated as R expressions. Per the "output" documentation on the knitr webpage:

Note all options in knitr can take values from R expressions, which brings the feature of conditional evaluation introduced in the main manual. In short, eval=dothis means the real value of eval is taken from a variable named dothis in the global environment; by manipulating this variable, we can turn on/off the evaluation of a batch of chunks.

In other words if you write some chunks like:

```{r label}
doNextChunk <- as.logical(rbinom(1,1,.5))
```

```{r conditional, eval = doNextChunk}
"hello world!"
```

Is there a way to have conditional markdown chunk execution in Rmarkdown?

Instead of using cat to print the solution from within an R code chunk, you could write the solution as you usually would in rmarkdown (i.e., with the usual combination of text, latex, and R code chunks), and use the parameter soln to comment out that section when you don't want to include the solution in the final document.

In the sample rmarkdown document below, if the parameter soln is FALSE, then the line r if(!params$soln) {"\\begin{comment}"} inserts \begin{comment} to comment out the solution (with matching code at the end to insert \end{comment}). I've also indented everything with two tabs, so that the question numbers are formatted with a hanging-indent. (If you like this format, you don't have to type the double-tab for each new paragraph or chunk. If you do this for one line, then each subsequent time you press the Enter key, the new line will automatically be formatted with the double-tab. Or, just type in all your text and code for a given question, then when you're done, highlight all of it and type tab twice.)

---
title: "Homework"
output: word_document
header-includes:
- \usepackage{comment}
params:
soln: TRUE
---

1. Fit the linear regression model $Y \sim X$ with the following data. Interpret the coefficient estimates.

```{r promptchunk, echo = TRUE}
set.seed(123)
X <- c(1, 1, 0, 0)
Y <- rnorm(4)
```

`r if(!params$soln) {"\\begin{comment}"}`

**Solution:**

Run the following R code to fit the linear regression model:
```{r, include = params$soln, echo = TRUE, results = "asis"}
fit1 = lm(Y ~ X)
```

To see a summary of the regression results, run the following code and review the output:

```{r, include = params$soln, echo=TRUE}
summary(fit1)
```
The interpretation of the intercept is....

Our estimate $\hat{\beta}_0$ is `r round(coef(fit1)[1], 2)`.

The estimated X coefficient $\hat{\beta}_1$ is `r round(coef(fit1)[2], 2)`.

This can be interpreted as....

`r if(!params$soln) {"\\end{comment}"}`

Also, instead of knitting the file above interactively, you can render both versions by running the render function in a separate R script. For example, assuming the file above is called hw.Rmd, open a separate R script file and run the following:

for (i in c(TRUE, FALSE)) {
rmarkdown::render("hw.Rmd",
params = list(soln = i),
output_file=ifelse(i, "Solutions.doc", "Homework.doc"))
}

Below is what Solutions.doc looks like. Homework.doc is similar, except everything from the bold word Solution: onward is excluded:

Sample Image

knitr: conditionally evaluate normal chunks

You can use a normal if block in the chunk. If you want an HTML formatted error message, you can use results='asis' in the chunk options. Like this:

<!--begin.rcode results='asis'
if (errors==1) {
cat('<p>You have an error</p>')
} else {
# r code to evaluate when errors!=1
}
end.rcode-->

How to evaluate all chunks in Rmarkdown

eval=TRUE is the default behaviour for .Rmd chunks, so you shouldn't need to explicitly add it to your chunks' options.

However, you do need to include {r} after your opening fences in order for the chunk to be recognised as R code and evaluated accordingly. Chunks that do not open with ```{r} will not be run, hence the problem you're seeing.

A working example might be:

```{r}
1+1
```
Some text

```{r}
2+2
```

To insert a new, empty chunk with the appropriate fences and {r}, you can press Ctrl + Alt+i on Windows, or + Option + i on Mac, or click this icon at the top right of the RStudio source pane (from memory, older versions of RStudio had an 'Insert' drop-down in that general area):

Sample Image

Conditionally display a block of text in R Markdown

You need a complete R expression, so you cannot break it into multiple blocks like you show, but if the results of a block are a text string then it will be included as is (without quotes), so you should be able to do something like:

`r if(show.text){"la la la"}`

and it will include the text if and only if show.text is TRUE.

How to not execute certain Rmarkdown chunks based on a parameter?

One of the knitr chunk options is eval=, which controls whether a chunk is evaluated. From that page:

  • eval: (TRUE; logical) whether to evaluate the code chunk; it can also be a numeric vector to select which R expression(s) to evaluate, e.g. eval=c(1, 3, 4) or eval=-(4:5).

One benefit of this is that it can use R variables in real-time, either generated within a previous chunk (eval=limit) or passed to a parameterized R-markdown document (as eval=params$limit).

Depending on your global options, you might always want/need to suppress printing the chunk, you can add echo=params$limit as well.



Related Topics



Leave a reply



Submit