Conditionally display a block of text in R Markdown

半城伤御伤魂 提交于 2019-12-17 22:36:16

问题


I am using knitr to parse an R Markdown document . Is there a way to conditionally display a block of text in R Markdown depending on a variable in the environment I pass into knitr?

For instance, something like:

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

Would print "la la la" in the resulting doc if show.text is true.


回答1:


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.




回答2:


You can do this using the "eval" chunk option. See http://yihui.name/knitr/options/.

```{r setup, echo=FALSE}
show_text <- FALSE
````

```{r conditional_block, eval=show_text}
print("this will only print when show.text is TRUE")
```

I've been using YAML config files to parameterize my markdown reports which makes them more reusable.

```{r load_config}
library(yaml)
config <- yaml.load_file("config.yaml")
```

...

```{r conditional_print, eval=config$show_text}
print("la la la")
````



回答3:


I find it easiest to do this by putting all of my text into a separate file and then include it from the main file with:

```{r conditional_print, child='text.Rmd', eval = show_text}
```

This has the advantage that you can still put inline R statements or other chunks into the child file, so that if you change your mind about what counts as optional text, you don't have to refactor your project.




回答4:


Here's a tweak to Paul Boardman's approach that gives proper markup in the output.

```{r setup, echo=FALSE}
show_text <- FALSE
```

```{r conditional_block, echo=FALSE, results='asis', eval=show_text}
cat("## Hey look, a heading!

lorem ipsum dolor emet...")
```

Even better, if we invoke the python engine to generate our output, we can use triple quoting to easily handle text that contains single or double quotes without needing to do anything fancy:

```{python, conditional_block_py, echo=FALSE, results='asis', eval=show_cond_text}
print("""
## Still a heading

Block of text with 'single quotes' and "double quotes"
""")
```



回答5:


The solutions above may be a little clunky for larger blocks of text and not great for certain situations. Let's say I want to create a worksheet for students with some questions and also use the same .Rmd file to generate a file with solutions. I used basic LaTeX flow control:

``` {r, include = F}
# this can be e.g., in a parent .Rmd and the below can be in child
solution <- TRUE 
```
\newif\ifsol
\sol`r ifelse(solution, 'true', 'false')`

Then I can do:

What is $2 + 2$

\ifsol
4
\fi

This way you can also create alternative blocks of text using

\ifsol
Alternative 1
\else
Alternative 2
\fi



回答6:


Another way to add markdown text conditionally is below. It uses the block "engine" which seems to run fine although I'm not sure how to make inline R evaluation working.

Note that I use the view_all switch defined in the YAML metadata to control whether or not the block is visible.

Also, note that both eval and include chunk options are needed. The first prevents errors during regular Run All in RStudio. The second prevents output with Knit.

---
title: "Conditional Output"
params:
  view_all: false
output:
  html_document: default
  pdf_document: default
---

```{block eval=FALSE, include=params$view_all}
# Some simple markdown.

Some things work: $2 + 2^2 = 3\cdot2$

Other does not: 2 + 2 = `r 2+2`
```



回答7:


I tried to define a function my.render(), which preprocesses the Rmd file, and depending on the commentout argument, either keeps the HTML commenting code (TRUE) in the Rmd file or removes them (FALSE). Then writes the preprocessed Rmd file into tmp.Rmd, and uses the usual render() function.

my.render <- function(input, commentout=FALSE, ...) {
  if (commentout == FALSE) {
    ## Delete the HTML comment lines from code
    txt <- readLines(input)
    txt[grepl(" *<!-- *| *--> *", txt)] <- ""
    write.table(txt, file="tmp.Rmd", sep="\n", quote=FALSE, row.names=FALSE, col.names=FALSE)
    render("tmp.Rmd", output_file=sub("Rmd","html",input), ...)
  } else {
    render(input, output_file=sub("Rmd","html",input), ...)
  }
}

It seemed to work. E.g.

<!--
This text with formulas $\alpha+\beta$ is visible, when commentout=FALSE.
-->


来源:https://stackoverflow.com/questions/25407102/conditionally-display-a-block-of-text-in-r-markdown

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!