J'utilise knitr pour analyser un document R. Markdown. Existe-t-il un moyen d’afficher de manière conditionnelle un bloc de texte dans R Markdown en fonction d’une variable de l’environnement dans lequel je passe dans knitr?
Par exemple, quelque chose comme:
`r if(show.text) {`
la la la
`r }`
Imprimera "la la la" dans la documentation résultante si show.text
est vrai.
Vous avez besoin d'une expression R complète. Vous ne pouvez donc pas la diviser en plusieurs blocs, mais si les résultats d'un bloc sont une chaîne de texte, ils seront inclus tels quels (sans guillemets). Vous devriez donc pouvoir faire quelque chose. comme:
`r if(show.text){"la la la"}`
et il inclura le texte si et seulement si show.text
est TRUE
.
Vous pouvez le faire en utilisant l'option "eval". Voir 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")
```
J'utilise les fichiers YAML config pour paramétrer mes rapports de démarques, ce qui les rend plus réutilisables.
```{r load_config}
library(yaml)
config <- yaml.load_file("config.yaml")
```
...
```{r conditional_print, eval=config$show_text}
print("la la la")
````
Je trouve cela plus facile de le faire en mettant tout mon texte dans un fichier séparé, puis en l'incluant à partir du fichier principal avec:
```{r conditional_print, child='text.Rmd', eval = show_text}
```
Cela présente l'avantage que vous pouvez toujours insérer des instructions R en ligne ou d'autres morceaux dans le fichier enfant. Ainsi, si vous changez d'avis sur ce qui compte comme texte facultatif, vous n'avez pas à refactoriser votre projet.
Voici une approche de Tweak à l'approche de Paul Boardman qui donne un balisage approprié dans la sortie.
```{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...")
```
Mieux encore, si nous appelons le moteur python pour générer notre sortie, nous pouvons utiliser des guillemets simples pour gérer facilement un texte contenant des guillemets simples ou doubles, sans avoir à faire des choses fantaisistes:
```{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"
""")
```
Les solutions ci-dessus peuvent être un peu maladroites pour des blocs de texte plus volumineux et pas géniales pour certaines situations. Supposons que je souhaite créer une feuille de calcul pour les étudiants avec quelques questions et utiliser le même fichier .Rmd pour générer un fichier avec des solutions. J'ai utilisé le contrôle de flux LaTeX de base:
``` {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')`
Alors je peux faire:
What is $2 + 2$
\ifsol
4
\fi
De cette façon, vous pouvez également créer des blocs de texte alternatifs en utilisant
\ifsol
Alternative 1
\else
Alternative 2
\fi
J'ai essayé de définir une fonction my.render()
qui prétraitement le fichier Rmd et, en fonction de l'argument commentout
, conserve le code de commentaire HTML (TRUE
) dans le fichier Rmd ou les supprime (FALSE
). Ecrit ensuite le fichier Rmd prétraité dans tmp.Rmd
et utilise la fonction render()
habituelle.
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), ...)
}
}
Cela semblait fonctionner. Par exemple.
<!--
This text with formulas $\alpha+\beta$ is visible, when commentout=FALSE.
-->