I cannot find information on whether it is possible to specify options for inline chunks in knitr. I've just tried specifying them, as in the regular chunk, but this gives an error.
What I need is to include R code with highlighting in a PDF, but without evaluating it. This can only happen with inline chunks due to the format of the context. Or perhaps there is another way to include highlighted code.
To provide an example, I need something in the lines of:
Some text about something with `r eval=FALSE 1+1` inside the sentence.
This particular syntax gives:
Error in parse(text = code, keep.source = FALSE) :
<text>:1:11: unexpected ','
1: eval=FALSE,
Thanks to Yihui you can do,
\documentclass{article}
<<setup, include=FALSE>>=
knit_hooks$set(inline = function(x) {
if (is.numeric(x)) return(knitr:::format_sci(x, 'latex'))
highr::hi_latex(x)
})
#
\begin{document}
the value of $\pi$ is \Sexpr{pi}, and the function to read a table is
\Sexpr{'read.table()'}.
<<test2>>=
rnorm(10)
#
\end{document}
Related
TL;DR
I want some latex commands (in this case \definecolor) to change in certain cases, so I want to create the text for these commands in R and have them written to the markup file during markup. I can't yet get it working perfectly using knitr hooks.
More Detail:
The number (and style) of colors I want to define in a .rnw file varies so I am avoiding hard-coding the \definecolor calls in the .rnw document.
It seems like I can do this with knitr hooks, and I'm very close. But I'm confused about a couple of things.
Here's a reproducible example. R file first
library(RColorBrewer)
library(knitr)
colNames <- c("one","two","three")
txtColors <- sub("#","",brewer.pal(6, "Dark2")[1:3])
# set the knitr hook to create color definitions within the rnw file
knitr::knit_hooks$set(setColors = function(before, options, envir) {
if (!before){
defs <- vector("list",length(txtColors))
for(i in 1:length(txtColors)){
defs[[i]] <- paste0("\\definecolor{",colNames[[i]],"Color}{HTML}{",txtColors[[i]],"}")
}
return(paste0("\\xglobal",unlist(defs), "\n"))
}
})
setwd(file.path("G:", "my", "working", "dir"))
knit2pdf("testColors_s.rnw")
and here an rnw file to go with it (name it "testColors_s.rnw")
\documentclass{article}
\usepackage{xcolor}
\begin{document}
<<setColorHook, setColors = TRUE>>=
#
\textcolor{oneColor}{The first color}
\textcolor{twoColor}{The second color}
\textcolor{threeColor}{The third color}
\end{document}
Question #1. I have to set the colors globally with \xglobal because (I guess) that knitr is putting these calls inside a kframe. Can I make a hook that avoids the kframe? Or doesn't require the xglobal call?
Question #2. I get this warning on run: Warning message: Package xcolor Warning: Incompatible color definition on input line 57. This is a color definition done by knitr, not me. Here is the offending line in the tex file:
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{kframe}
How can I avoid this warning or keep knitr from creating this line?
Any tips on doing any part of this would be greatly appreciated.
Thanks in advance.
This seems like kind of a hack, but I figured out a solution using the document hook instead of a chunk hook. This fixes both problems (xglobal not longer needed and the extra definecolor is not created). Better solutions are welcome.
Reproducible example, R file:
library(RColorBrewer)
library(knitr)
colNames <- c("one","two","three")
txtColors <- sub("#","",brewer.pal(6, "Dark2")[1:3])
defs <- vector("list",length(txtColors))
for(i in 1:length(txtColors)){
defs[[i]] <- paste0("\\\\definecolor{",colNames[[i]],"Color}{HTML}{",txtColors[[i]],"}")
}
knit_hooks$set(document = function(x) {
sub('%CustomColorDefsHere', paste0(unlist(defs), "\n", collapse = ""), x)
})
setwd(file.path("G:", "my", "working", "dir"))
knit2pdf("testColors_s.rnw")
and the rnw file
\documentclass{article}
\usepackage{xcolor}
%CustomColorDefsHere
\begin{document}
\textcolor{oneColor}{The first color}
\textcolor{twoColor}{The second color}
\textcolor{threeColor}{The third color}
\end{document}
I hope this is useful for someone ...
I just found this awesome technique to put the code used in the .Rmd file in the appendix (of that same file).
However, I am using R Sweave and not R Markdown and I would like to know if there exists a similar way to put all the code at the end in a unique chunk. The code to do that in Markdown does not work in Sweave. I precise that, unlike this post, I do not have a separate .R file where the calculations are made. Everything is done in the .Rnw file.
Does anybody know how to do it?
Edit : a reproducible example
\documentclass[11pt, twocolumn]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\begin{document}
\SweaveOpts{concordance=TRUE}
<<reg2, echo=FALSE, print=FALSE>>=
head(mtcars)
#
<<reg3, echo=FALSE, print=FALSE>>=
head(iris)
#
\section*{Appendix}
% the place where I could like to put the whole code
\end{document}
This chunk works to include the code:
<<echo=FALSE, eval=TRUE>>=
filename <- tempfile(fileext=".R")
Stangle("test.Rnw", output = filename, quiet = TRUE)
cat(readLines(filename), sep = "\n")
#
When I include that in your example file, I see this:
I think it's possible to modify the format a bit; see ?Rtangle for some details. Similar things are possible with knitr, but it's more flexible. I suspect the best method would be similar to the one you found for RMarkdown.
I'm working on my first R notebook which works pretty well, except for one issue.
I'd like to be the numbers that I output inline with
`r realbignumber`
to have commas as separator and max 2 decimal points: 123,456,789.12
In order to achieve this, I added a chunk at the beginning of my document, which contains...
```{r setup}
knitr::opts_chunk$set(echo = FALSE, warning=FALSE, cache = TRUE, message = FALSE)
knitr::opts_chunk$set(inline = function(x){if(!is.numeric(x)){x}else{prettyNum(round(x,1), big.mark = ",")}})
options(scipen=999)
```
The suppression of scientific numbers works like a charm, so the chunk is definitely executed. However, formatting of the inline output of numbers does not work.
Any ideas why that could be?
Do these kinds of settings generally not work with R notebooks?
Edit:
The solution suggested here also has no effect on the output format of numbers.
Here is an example illustrating two ways to print a large number in an R Markdown document. First, code to use the prettyNum() function in an inline R chunk.
Sample document where we test printing a large number. First set the number in an R chunk.
```{r initializeData}
theNum <- 1234567891011.03
options(scipen=999,digits=16)
```
The R code we'll use to format the number is: `prettyNum(theNum,width=23,big.mark=",")`.
Next, print the large number. `r prettyNum(theNum,width=23,big.mark=",")`.
The alternative of using chunk options works as follows.
Now, try an alternative using knitr chunks.
```{r prettyNumHook }
knitr::knit_hooks$set(inline = function(x) { if(!is.numeric(x)){ x }else{ prettyNum(x, big.mark=",",width=23) } })
```
Next, print the large number by simply referencing the number in an inline chunk as `theNum`: `r theNum`.
When both chunks of code are embedded in an Rmd file and knit, the output is as follows, showing that both techniques produce the same result.
regards,
Len
Suppose that the command isn't important enough to have it on the separate line, But I still want it to be visible along the result, I know there is ` r inlinestr` in R Markdown, but it I can't pass echo=T to it. I want the result to be something like this:
You could use backticks, which would give you the monospace font, but not the gray background shading:
f. There are `sum(is.na(df$Height)) =` `r sum(is.na(df$Height))` missing Height values.
I just ran across this question that I attempted to answer about two years ago and thought of a way to get both the code and its evaluated output in a single inline statement. We just need a helper function. Below is an example. The code is entered as a text string and the function returns both the code and the result of evaluating the code:
---
title: "RMarkdown teaching demo"
author: "whoever"
output: pdf_document
---
```{r}
fnc = function(expr) {
paste(expr, " = ", eval(parse(text=expr)))
}
# Add some missing values
iris$Sepal.Length[c(3,5,10)] = NA
```
f. There are `r fnc("sum(is.na(iris$Sepal.Length))")` missing height values.
Below is the output.
It works, but there are two issues. First, the code is not in monospace font. Second, the code is not highlighted with a gray background.
I thought that I could get monospace font with the latex \texttt{} tag.
```{r}
fnc = function(expr) {
paste("\\texttt{", expr, " = ", eval(parse(text=expr)), "}", sep="")
}
```
This appears to return the desired string when run interactively ("\\texttt{sum(is.na(iris$Sepal.Length)) = 3}"), but throws the following error when I try to knit the document:
! Extra }, or forgotten $.
<recently read> \egroup
l.163 ...texttt{sum(is.na(iris$Sepal.Length)) = 3}
I thought I could get highlighting with the \hl{} tag (which also requires \usepackage{color, soul} in the latex header):
```{r}
fnc = function(expr) {
paste("\\hl{", expr, " = ", eval(parse(text=expr)), "}", sep="")
}
```
However, once again, this throws an error:
! Argument of \SOUL#addmath has an extra }.
<inserted text>
\par
l.161 ...re \hl{sum(is.na(iris$Sepal.Length)) = 3}
Both texttt{} and \hl{} work without a problem when used with regular text inside an rmarkdown document.
So, I'm not sure how to get the monospace font or highlighted text, but at least this takes a step toward code + evaluated code from a single inline R statement. Hopefully, someone with more knowledge of computing on the language and outputting latex markup can provide more insight into how to get this to work as desired.
Sounds like it should be a common problem, but I didn't find an obvious trick.
Consider the knitr Rnw file below,
\documentclass[twocolumn, 12pt]{article}
\usepackage{graphicx}
\begin{document}
%\SweaveOpts{dev=pdf, fig.align=center}
\begin{figure*}
<<aaa, fig.width=8, fig.height=5, fig.show=hold>>=
plot(1,1)
#
\end{figure*}
\end{document}
I would like this wide figure to span two columns, using a {figure*} LaTeX environment. Is there a hook for that?
EDIT: wrapping the chunk in figure* gives the following output.
Two facts:
knitr makes everything accessible for you, so LaTeX tricks are often unnecessary;
there is a chunk hook with which you can wrap your chunk results;
A simple-minded solutions is:
knit_hooks$set(chunk = function(x, options) {
sprintf('\\begin{figure*}\n%s\n\\end{figure*}', x)
})
I leave the rest of work to you to take care of more details in options (e.g. when options$fig.keep == 'none', you should not wrap the output in figure*). You may want to see how the default chunk hook for LaTeX is defined in knitr to know better how the chunk hook works.
However, in this case, I tend to write the LaTeX code by myself in the document instead of automatically creating it. After you have got figure*, you may start to think about \caption{} and \label{} (not hard, but I still want to see them in LaTeX).
Not sure about how knitr but for Sweave (and basic latex) there is in fact a trick: have the R code produce a pdf file, and then use standard \includegraphics to pull it in.
So with this:
\documentclass[twocolumn, 12pt]{article}
\usepackage{graphicx}
\begin{document}
%\SweaveOpts{dev=pdf}
<<aaa,fig=FALSE,print=FALSE,echo=FALSE>>=
pdf("mychart.pdf", width=6, height=3)
set.seed(42)
plot(cumsum(rnorm(100)), type='l', main="yet another random walk")
invisible(dev.off())
#
\begin{figure*}
\includegraphics{mychart.pdf}
\end{figure*}
\end{document}
I got the document below (which I then converted from pdf to png):
I also had a similar problem while preparing a figure that should span two columns in a IEEE two-column conference paper.
Setting the chunk hook caused some strange error in my setup.
Even this simple hook: knit_hooks$set(chunk = function(x, options) x)
But after looking into knitr::opts_chunk$get(), I realized that simply setting fig.env="figure*" solves the problem in an elegant way.
Here is how my chunk looks like in an Rnw file:
<<fig1, fig.width=18, fig.height=6, fig.env="figure*">>=
#