If else in R Markdown, colored text - r

I have a R Markdown child-file, which should produce different output based on a R-condition .
My code (sorry it is not reproducible):
{r results='asis', echo = FALSE}
if (class(robject) == "character") {
cat("**R object is empty!**") # This text should appear in RED in the Output (HTML) file.
} else {
cat("### Data columns\n")
cat("\n")
kable(robject)
cat("\n")
}
What the code does:
If my robject is not a data.frame it is set to an empty string (robject <- ""). With this "trick" it is possible to if_else about robject.
In my R Markdown file it should be printed either "R object is empty!" or a summary of the dataset (which is a data.frame again). If the dataset is empty, the text should appear in RED!
Two questions:
How to print the text in RED (or every other color) using the cat command as in the example above?
(I tried text_spec from kableextra as mentioned here, I tried crayron-Package as well and I tried to enter html_tags with print/cat . Neither worked!)
Maybe it is better to if else outside the R Chunk. Unfortunately this approach did not work either enter link description here
Thank you for any help.
If you need some further information, please ask me for it. Thanks!

For HTML you can wrap the text in <span> and use CSS to set the color. If you need to do this more than a couple of times, you can wrap it up in a simple function.
```{r results='asis', echo = FALSE}
cat_color <- function(message, color = "black") cat(sprintf("<span style = \"color: %s;\">%s</span>\n\n", color, message))
robject <- "some text"
if (class(robject) == "character") {
cat_color("**R object is empty!**" , "red") # This text should appear in RED in the Output (HTML) file.
} else {
cat("### Data columns\n")
cat("\n")
kable(robject)
cat("\n")
}
```

Related

Printing from a function in Rmarkdown that allows newlines and escaping Markdown and Latex commands

I am trying to write a function for use in Rmarkdown that allows newlines, the use of variables and nested functions as well as Markdown and Latex commands for outputting pdf's. The function would be used to, for example, generate formatted sections in Rmarkdown documents (I realize that I could use Latex' \titleformat{\section} to achieve this in the particular case of sections but I would also like to be able to display, for example, JSON data with a certain formatting in Rmarkdown).
Here is an example of a function that doesn't work but that will hopefully illustrate what I would like to achieve:
---
title: "Printing from function with newlines and escaped Markdown/Latex commands"
author: "Jono3030"
output: pdf_document
---
thirdLineFunction <- function() {
thirdLine <- "**This is the third line in bold**"
return(thirdLine)
}
newLinePrinting <- function(exampleVar) {
firstLine <- "This is the first line"
secondLine <- sprintf("This is the %s line", exampleVar)
thirdLine <- thirdLineFunction()
fourthLine <- "\\textit{This is the fourth line in italics}"
cat(firstLine, "\n\n", secondLine, "\n\n", thirdLine, "\n\n", fourthLine)
}
Using cat and including newline characters results in non of the strings being printed i.e. only the title and author appear in the pdf. Even if printing with cat works, however, Markdown and Latex code does not get escaped. Using print, sprintf or paste instead of cat does not print newlines and some of these methods include indices ([1] etc.) and quotations marks in the outputs which is not desired.
The desired output that renders correctly to a pdf from Rmarkdown would be:
This is the first line
This is the second line
**This is the third line in bold**
\textit{This is the fourth line in italics}
I also tried to print from the function with a for loop:
test <- function() {
o1 <- "This is text"
o2 <- "This is \\textbf{also} text"
o3 <- thirdLineFunction()
o4 <- "This is *text*"
newline <- ""
listvar <- c(o1, newline, o2, newline, o3, newline, o4)
for (i in listvar) {
print(noquote(i))
}
}
Although closer to what I want it didn't work either as I could not get rid of the indices:
[1] This is text
[1]
[1] This is \\textbf{also} text
[1]
[1] **This is the third line in bold**
[1]
[1] This is *text*
Using cat to omit the indices resulted in the Markdown and Latex commands not being escaped.
Using the above for loop with a combination of paste and cat didn't work either:
for (i in listvar) {
paste(i, collapse = '\n') %>% cat()
}
Of note might be that cat does work when I execute code in the console but the output does not show in the rendered pdf. I also tried to render to html which doesn't work either.
Again, eventually I would like to be able to print something like this using a function:
## Section Title
\vspace{1em}
\hrulefill
Or:
This is the **first** line printed from a JSON file
\vspace{1em}
This is the \textbf{second} line printed from a JSON file
\vspace{1em}
The output should then be rendered correctly into pdf, respecting the Markdown and Latex formatting.
Thank you in advance for your time and help!
I figured out a way to do what I wanted using paste():
stackOverflow <- function() {
paste(c(
"This is the **first** line printed from a JSON file",
"\\vspace{1em}",
"\n",
"This is the \\textbf{second} line printed from a JSON file",
"\n",
"\\vspace{1em}"
), collapse = "\n")
}
Putting the multiline output in a list nested in paste() using collapse = "\n" results in the following when executed:
[1] "This is the **first** line printed from a JSON file\n\\vspace{1em}\nThis is the \textbf{second} line printed from a JSON file\n\\vspace{1em}"
Which gets rendered correctly:
It's not perfect as Rmarkdown, for example, requires two spaces at the end or a blank line between text to put it in a new line hence why I added the extra "\n" characters. For now it works, however, so I'm marking it as the correct answer in the hopes that it will help others. If someone can come up with a better solution I'll happily mark theirs as correct.
Edit:
The extra line/two spaces required by markdown can, in most cases, be solved by collapsing with two line break characters like so: "\n\n"
This changes the above code to:
stackOverflow <- function() {
paste(c(
"This is the **first** line printed from a JSON file",
"\\vspace{1em}",
"This is the \\textbf{second} line printed from a JSON file",
"\\vspace{1em}"
), collapse = "\n\n")
}

How can I hide code blocks in xaringan presentation?

I'm running some plot code in markdown to generate a plot in a xaringan presentation. The code works but is a little long and so takes up the whole presentation slide forcing the actual plot off the edge (see img).
How can I hide the code block generating the plot?
Also how can I compress the code block with a scroll bar?
```{r}
r_exp.fun <- function(r = 0.05, N_pop = 10, t = 150)
{
N <- vector("numeric", length = t)
N[1] <- N_pop
for (i in 2:t)
{
N[i] <- N[i-1] + (N[i-1] * r)
}
return(N)
}
args_list <- list(0.045, 0.055, 0.06)
matplot(
mapply(
r_exp.fun,
r = args_list
)
,type = "l")
abline(h = list(7052, 29150, 59000))
```
The alternative is of course to save as an image but if possible I would prefer to be able keep the code as a resource for anyone with the link.
Thanks!
As alistaire already mentioned in the comments, RMarkdown has various chunk options to customize the output.
For your problem the option echo needs to be set to FALSE.
The other options (from https://rmarkdown.rstudio.com/lesson-3.html):
include = FALSE
prevents code and results from appearing in the finished file. R Markdown still runs the code in the chunk, and the results can be used by other chunks.
echo = FALSE
prevents code, but not the results from appearing in the finished file. This is a useful way to embed figures.
message = FALSE
prevents messages that are generated by code from appearing in the finished file.
warning = FALSE
prevents warnings that are generated by code from appearing in the finished.
fig.cap = "..."
adds a caption to graphical results.

Change color of error messages in RMarkdown code output (HTML, PDF)

Is there a way to automatically make text color of errors red in R Markdown without manually editing the HTML later.
---
title: ""
---
#### Example 1
```{r e1, error = TRUE}
2 + "A"
```
#### Example 2
```{r e2, error = TRUE}
2 + 2
```
In the above code, output of Example 1 would have to be red. Currently, I edit the generated HTML (add style="color:red;" to the appropriate tag) but I am wondering if there is an automatic way. Assume that it is not known before knitting whether the code will generate error.
1. Use a knitr hook
The preferred solution is to use the output hook for errors:
```{r}
knitr::knit_hooks$set(error = function(x, options) {
paste0("<pre style=\"color: red;\"><code>", x, "</code></pre>")
})
```
Output hooks in general allow us to control the output of different parts of our R code (the whole chunk, the source code, errors, warnings, ...). For details check https://yihui.name/knitr/hooks/#output-hooks.
2. Quick and dirty solution using JS/jQuery
And this is my "quick and dirty" solution using jQuery/Javascript. Just add it beneath the YAML header.
Might not be bulletproof, since it checks for error messages using the string "Error" which might occur in other applications as well.
<script type="text/javascript">
$(document).ready(function() {
var $chks = $("pre:not(.r) > code");
$chks.each(function(key, val) {
cntnt = $(this).html();
if (cntnt.indexOf("Error") != -1) {
$(this).css('color', 'red');
}
})
})
</script>
I stumbled here because I had the same question but for PDF output rather than HTML.
It turns out combining #Martin Schmelzer's Solution with some hints from #Yihui Xie found here helps to achieve the same behavior in a PDF output.
Add \usepackage{xcolor} to your YAML header and the following chunk to your .Rmd file.
```{r}
color_block = function(color) {
function(x, options) sprintf('\\color{%s}\\begin{verbatim}%s\\end{verbatim}',
color, x)
}
knitr::knit_hooks$set(error = color_block('red'))
```
The result is red error messages like

How to syntax highlight inline R code in R Markdown?

This question is similar to consistent code html inline and in chunks with knitr. Instead of .Rhtml documents, I want to highlight inline R code in R Markdown documents, e.g., after `r "plot(cars, main = 'A scatterplot.')"` is compiled through rmarkdown, the tokens like plot should be highlighted. By default, R code chunks are syntax highlighted, but there is no way to highlight inline R code.
Here is one solution using the development version of the highr package (devtools::install_github('yihui/highr')). Basically you just define your custom LaTeX commands to highlight the tokens. highr:::cmd_pandoc_latex is a data frame of LaTeX commands that Pandoc uses to do syntax highlighting.
head(highr:::cmd_pandoc_latex)
## cmd1 cmd2
## COMMENT \\CommentTok{ }
## FUNCTION \\NormalTok{ }
## IF \\NormalTok{ }
## ELSE \\NormalTok{ }
## WHILE \\NormalTok{ }
## FOR \\NormalTok{ }
Then you can redefine the inline hook of knitr:
---
output:
pdf_document:
keep_tex: yes
---
```{r include=FALSE}
local({
hi_pandoc = function(code) {
if (knitr:::pandoc_to() != 'latex') return(code)
if (packageVersion('highr') < '0.6.1') stop('highr >= 0.6.1 is required')
res = highr::hi_latex(code, markup = highr:::cmd_pandoc_latex)
sprintf('\\texttt{%s}', res)
}
hook_inline = knitr::knit_hooks$get('inline')
knitr::knit_hooks$set(inline = function(x) {
if (is.character(x) && inherits(x, 'AsIs')) hi_pandoc(x) else hook_inline(x)
})
})
```
Test inline R code: `r I("plot(cars, main = 'A scatterplot.')")`.
Normal inline code `r pi`.
A code block:
```r
plot(cars, main = 'A scatterplot.')
1 + 2 # a comment
```
I used I() as a convenient marker to tell the character strings to be syntax highlighted from normal character strings. It is just an arbitrary choice. PDF output:
This is not a perfect solution, though. You will need to tweak it in some cases. For example, most special LaTeX characters are not escaped, such as ~. You may need to process the LaTeX code returned by hi_pandoc() by gsub().
Personally I find multiple colors in inline output distracting, so I would not syntax highlighting it, but this is entirely personal taste.
Now-a-days:
Here is some `plot(cars, main = 'A scatterplot.')`{.R} inline R code
Well, I don't know specifically about R and the way you're using it, but for most languages (pandoc uses the skylighting pkg to do this), you can do inline code blocks with the above syntax.

How do I set conditional LaTeX code using R?

Suppose in my R/Sweave created LaTeX document, I want to have \subsection{Foo} if in my R code we have that x==1, whereas if x==2 in my R code I want \subsection{Bar} to be displayed.
How do I accomplish this? I know how to include R code by encapsulating it in <<>>= and # but I'm not sure how to do something such as the following (perhaps nonsensical) pseudo-code:
if(x==1)
Show \subsection{Foo} in LaTeX document
else if(x==2)
Show \subsection{Bar} in LaTeX document
What I also want to do that is very closely related is have subheading \subsection{z} in my LaTeX document, where z is defined strictly in my R code as some arbitrary string that I can toggle.
\Sexpr{} can evaluate expressions inline:
Show \subsection{\Sexpr{if(x==1) "Foo" else "Bar"}} in LaTeX document
\subsection*{\Sexpr{z}}
Use results=tex and cat the LaTeX code you want.
<<results=tex>>=
if(x==1) {
z <- "Foo"
} else if(x==2) {
z <- "Bar"
}
cat("\\subsection{", z, "}\n", sep="")
#

Resources