在R标记中有条件地显示文本块

在R标记中有条件地显示文本块,r,knitr,r-markdown,R,Knitr,R Markdown,我正在使用knitr解析R标记文档。有没有一种方法可以根据我传递到knitr的环境中的变量,有条件地在R标记中显示文本块 例如,类似于: `r if(show.text) {` la la la `r }` `r if(show.text){"la la la"}` 如果show.text为真,将在生成的文档中打印“la” 您需要一个完整的R表达式,因此不能像您所展示的那样将其拆分为多个块,但如果块的结果是文本字符串,则它将按原样包含(不带引号),因此您应该能够执行以下操作: `r if

我正在使用knitr解析R标记文档。有没有一种方法可以根据我传递到knitr的环境中的变量,有条件地在R标记中显示文本块

例如,类似于:

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

如果
show.text
为真,将在生成的文档中打印“la”

您需要一个完整的R表达式,因此不能像您所展示的那样将其拆分为多个块,但如果块的结果是文本字符串,则它将按原样包含(不带引号),因此您应该能够执行以下操作:

`r if(show.text) {`
  la la la
`r }`
`r if(show.text){"la la la"}`
当且仅当
show.text
TRUE
时,它将包含文本。您可以使用“eval”块选项执行此操作。看


我发现将我的所有文本放在一个单独的文件中,然后将其从主文件中包含,这样做最简单:

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

这样做的好处是,您仍然可以将内联R语句或其他块放入子文件中,这样,如果您改变了对哪些内容是可选文本的看法,就不必重构项目。

这里是对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...")
```

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

``` {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')`
通过这种方式,您还可以使用

\ifsol
Alternative 1
\else
Alternative 2
\fi

我试图定义一个函数
my.render()
,该函数预处理Rmd文件,并根据
commentout
参数,在Rmd文件中保留HTML注释代码(
TRUE
),或删除它们(
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), ...)
  }
}

my.render下面是有条件添加标记文本的另一种方法。它使用了
“引擎”,虽然我不确定如何使内联R计算工作,但它似乎运行良好

注意,我使用YAML元数据中定义的
view\u all
开关来控制块是否可见

另外,请注意,
eval
include
区块选项都是必需的。 第一种方法防止在RStudio中定期运行所有代码时出错。 第二个防止针织输出

---
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`
```

上述公认的答案适用于内联内容

对于块内容(标记文本的几个段落之一),knitr包含一个
asis
引擎,该引擎允许根据块选项
echo=FALSE
echo=TRUE

文档中的示例

`{r}

getRandomNumber不幸的是,我不确定
knitr
,但是你可以用
pander
类型的标签轻松做到这一点:这太棒了,应该被接受。甚至扩展到更复杂的标记输入,例如
`r if(TRUE){“#Header\n这是在Header下\n\n##subheader\n这是在sub下?”}
我喜欢你的解决方案。这使得处理更大的报告更容易管理。请注意,与之相反,此解决方案使用“输出标记”打印文本,并且不会逐字显示。这是因为缺少
results='asis'
asis
knitr引擎更适合此任务:我欣赏Python解决方案,但如果您需要在该代码块中使用R对象,则会变得很困难。@ctbrown如果您需要从降价内部运行R代码,例如
cat(“今年,我们销售了'R quartlysales`产品单位”)
那么我在这里介绍的python解决方案和R解决方案都不适合您。你不必在降价时直接调用R代码,只需通过分段粘贴来构建所需的文本,例如
cat(粘贴(“今年,我们售出了”,quarterlySales,“产品单位”)
。如果这不是你的意思,请随意详细说明你的用例,我会看看我能想出什么。这很好,非常适合我的需要。条件块似乎只在编织输出时才起作用。它不允许我突出显示块中的一行代码并执行它,每次都报告错误并中止R会话<代码>{r conditional_block,echo=FALSE,results='asis',eval=show_text}cat(“##嘿,看,一个标题!lorem ipsum dolor emet…”)
类中的错误(obj)knitr
asis
引擎就是为这个而设计的,它避免了使用
cat
和引用问题。嗨米兰:我试图复制你的想法,但没有成功(都是
备选方案
s打印输出)。我希望能够使它工作!我的代码都在一个Rmd下(没有孩子).有什么想法吗?我非常感谢您的帮助。您好@MarianMinar,我刚刚将上面的代码复制到一个新的.Rmd中,它工作得很好。请确保在R代码块中创建
解决方案
对象,因为它习惯于将\sol设置为true或false。@MilanValášek:对我来说,它在HTML中不起作用,只有在LaTex中。如果您找到一个解决方案作为bea与你的HTML一样实用和简单,我会非常感兴趣的!@mavericks是的,我刚刚开始解决同样的问题。如果有人能帮忙,那就太好了!@mavericks我最终编写了一个函数,它做了大量的后处理,与Tommi Härkänen在下面所做的不太一样。然而,一个简单的解决方案是用插入(或不插入)HTML注释标记的
R
if-else语句替换LaTeX if-else在可选文本块周围。注释掉的文本仍将在HTML文件中,但不可见。您甚至可以自己编写一个函数,使其更高效……这些
include=
参数是否可以在反应上下文中进行选择
\ifsol
Alternative 1
\else
Alternative 2
\fi
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.
-->
---
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`
```