有条件地在R Markdown中显示一个文本块

时间:2014-08-20 14:16:54

标签: r knitr r-markdown

我正在使用knitr来解析R Markdown文档。有没有办法根据我传入knitr的环境中的变量有条件地显示R Markdown中的文本块?

例如:

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

将打印" la la la"如果show.text为真,则在生成的文档中。

8 个答案:

答案 0 :(得分:32)

你需要一个完整的R表达式,所以你不能像你展示的那样把它分成多个块,但如果一个块的结果是一个文本字符串,那么它将按原样包含(没有引号),所以你应该能够做类似的事情:

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

并且当且仅当show.textTRUE时才会包含该文字。

答案 1 :(得分:20)

您可以使用" eval"块选项。请参阅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")
```

我一直在使用YAML配置文件来参数化我的降价报告,这使得它们更具可重用性。

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

...

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

答案 2 :(得分:13)

通过将所有文本放入单独的文件然后将其包含在主文件中,我发现最简单的方法是:

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

这样做的好处是,您仍然可以将内联R语句或其他块放入子文件中,这样,如果您改变主意关于什么算作可选文本,则无需重构项目。

答案 3 :(得分:10)

这是对Paul Boardman的方法的调整,它在输出中提供了适当的标记。

```{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...")
```

更好的是,如果我们调用python引擎来生成输出,我们可以使用三重引号来轻松处理包含单引号或双引号的文本,而无需做任何花哨的事情:

```{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"
""")
```

答案 4 :(得分:2)

对于较大的文本块,上面的解决方案可能有点笨拙,对某些情况来说并不是很好。让我们说我想为有一些问题的学生创建一个工作表,并使用相同的.Rmd文件生成一个包含解决方案的文件。我使用了基本的LaTeX流量控制:

``` {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')`

然后我可以做:

What is $2 + 2$

\ifsol
4
\fi

这样您还可以使用

创建替代文本块
\ifsol
Alternative 1
\else
Alternative 2
\fi

答案 5 :(得分:2)

下面是有条件地添加降价文字的另一种方法。它使用block“引擎”,尽管我不确定如何使内联R评估正常运行,但它似乎运行良好。

请注意,我使用YAML元数据中定义的view_all开关来控制该块是否可见。

此外,请注意,evalinclude块选项都需要。 第一个可以防止在RStudio常规Run All期间出错。 第二个阻止使用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`
```

答案 6 :(得分:1)

上面接受的答案适用于内嵌内容。

对于块内容(Markdown 文本的几个段落之一),knitr 包含一个 asis 引擎,该引擎允许根据块选项 echo = FALSE 或 { 有条件地包含 Markdown 内容{1}}

文档中的示例 https://bookdown.org/yihui/rmarkdown-cookbook/eng-asis.html

echo = TRUE

如果您需要包含更复杂的内容,例如带有代码块的 R Markdown 文档,那么子文档可能很有用。见https://bookdown.org/yihui/rmarkdown-cookbook/child-document.html

答案 7 :(得分:0)

我试图定义一个函数my.render(),该函数预处理Rmd文件,并根据commentout参数,将HTML注释代码(TRUE)保留在Rmd文件中,或者删除它们(FALSE)。然后将预处理的Rmd文件写入tmp.Rmd,并使用通常的render()函数。

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), ...)
  }
}

似乎有效。例如

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