In a vignette demonstrating how to use a Suggested package, I have something like this:
if (suggested_package_not_available) {
knitr::opts_chunk$set(eval = FALSE)
}
This means that the vignette still runs etc. although the Suggested package is not available. It just shows the code, not the results.
Can I do something similar for inline R code (`r code`)?
Maybe a hook that uses a regex (a la `r [^`]+`) to add two backticks around the inline code so that the inline code is showed instead of evaluated (which would normally cause an error because the chunks are no longer evaluated)?
A trick might be to print a string or evaluate the expression:
check_code <- function(expr, available){
if(available){
eval(parse(text = expr))
} else {
expr
}
}
check_code("1+1", TRUE)
check_code("1+1", FALSE)
It looks like double backticks before and after as well as breaking the line just after `r will work.
A more thorough explanation at yihui's site: https://yihui.org/knitr/faq/
(#7)
For inline R code, you may use the function knitr::inline_expr() (available in knitr >= v1.8). If you are writing an R Markdown document, you can use a trick: break the line right after `r (no spaces after it), and wrap the whole inline expression in a pair of double backticks, e.g.,
This will show a verbatim inline R expression `r
1+1` in the output.
Related
Using knitr and R Markdown, I can produce a tabularised output from a matrix using the following command:
```{r results='asis'}
kable(head(x))
```
However, I’m searching for a way to make the kable code implicit since I don’t want to clutter the echoed code with it. Essentially, I want this:
```{r table=TRUE}
head(x)
```
… to yield a formatted tabular (rather than the normal output='markdown') output.
I actually thought this must be pretty straightforward since it’s a pretty obvious requirement, but I cannot find any way to achieve this, either via the documentation or on the web.
My approach to create an output hook fails because once the data arrives at the hook, it’s already formatted and no longer the raw data. Even when specifying results='asis', the hook obtains the output as a character string and not as a matrix. Here’s what I’ve tried:
default_output_hook <- knit_hooks$get('output')
knit_hooks$set(output = function (x, options)
if (! is.null(options$table))
kable(x)
else
default_output_hook(x, options)
)
But like I said, this fails since x is not the original matrix but rather a character string, and it doesn’t matter which value for the results option I specify.
Nowadays one can set df_print in the YAML header:
---
output:
html_document:
df_print: kable
---
```{r}
head(iris)
```
I think other answers are from a time when the following didn't work, but now we can just do :
```{r results='asis', render=pander::pander}
head(x)
```
Or set this for all chunks in the setup chunk, for instance :
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, render=pander::pander)
```
Lacking a better solution I’m currently re-parsing the character string representation that I receive in the hook. I’m posting it here since it kind of works. However, parsing a data frame’s string representation is never perfect. I haven’t tried the following with anything but my own data and I fully expect it to break on some common use-cases.
reparse <- function (data, comment, ...) {
# Remove leading comments
data <- gsub(sprintf('(^|\n)%s ', comment), '\\1', data)
# Read into data frame
read.table(text = data, header = TRUE, ...)
}
default_output_hook <- knit_hooks$get('output')
knit_hooks$set(output = function (x, options)
if (is.null(options$table))
default_output_hook(x, options)
else {
extra_opts <- if (is.list(options$table)) options$table else list()
paste(kable(do.call(reparse, c(x, options$comment, extra_opts))),
collapse = '\n')
}
)
This will break if the R markdown comment option is set to a character sequence containing a regular expression special char (e.g. *), because R doesn’t seem to have an obvious means of escaping a regular expression.
Here’s a usage example:
```{r table=TRUE}
data.frame(A=1:3, B=4:6)
```
You can pass extra arguments to the deparse function. This is necessary e.g. when the table contains NA values because read.table by default interprets them as strings:
```{r table=list(colClasses=c('numeric', 'numeric'))}
data.frame(A=c(1, 2, NA, 3), B=c(4:6, NA))
```
Far from perfect, but at least it works (for many cases).
Not exactly what you are looking for, but I am posting an answer here (that could not fit in a comment) as your described workflow is really similar to what my initial goal and use-case was when I started to work on my pander package. Although I really like the bunch of chunk options that are available in knitr, I wanted to have an engine that makes creating documents really easy, automatic and without any needed tweaks. I am aware of the fact that knitr hooks are really powerful, but I just wanted to set a few things in my Rprofile and let the literate programming tool its job without further trouble, that ended to be Pandoc.brew for me.
The main idea is to specify a few options (what markdown flavour are you using, what's your decimal mark, favorite colors for your charts etc), then simply write your report in a brew syntax without any chunk options, and the results of your code would be automatically transformed to markdown. Then convert that to pdf/docx/odt etc. with Pandoc.
I have an R vector of filepaths for pdf figures I would like to put into my knitr document and knit to html. I see that I can get a single pdf to be included with
knitr::include_graphics(filepaths[1])
My filepaths vector is long and changes size between document compilations. Is there a method of including them all in one go. I had imagined this would work.
for(i in filepaths){knitr::include_graphics(i)}
Had also tried:
for(i in filepaths){ print("![](", filepaths[i], ")" ) }
knitr::include_graphics() is vectorized, so the answer is simply:
knitr::include_graphics(filepaths)
Your first solution does not work because knitr::include_graphics() needs to be the top-level expression. Your second solution does not work because you should use cat() instead of print(), and the chunk option results='asis'.
There are several advantages of using include_graphics() over cat() + results='asis'.
Try using cat instead of include_graphics. For example:
for(i in 1:length(filepaths) {
cat("![](", filepaths[i], ")")
}
This is general Markdown syntax: ![NAME](PATH).
With this solution you will need to use results = "asis" in chunk header.
I am using knitr for a report wherein I have a lot of inline output text, mostly numeric values, using \Sexpr{}. I want to highlight All these inline outputs in my generated pdf.
Example code:
\documentclass[12pt]{article}
\begin{document}
<<echo=FALSE, include=FALSE>>=
N <- 100 # Total
N_f <- 60 # Women
#
There were \Sexpr{N} people in the company, \Sexpr{N_f} women and \Sexpr{N - N_f} men.
\end{document}
Hence, in the output all the number should be highlighted, i.e. with a shaded background (similar to using with \hl{} with the \usepackage{soul}).
It seems to me that the solution would use one of the inline output hooks. Another possibility might be to write a LaTeX function which search all the \Sexpr{...} expressions in the entire document and highlights them in the generated pdf. I am still learning and can not figure out how to implement these.
Thanks for any help or hints.
Note: The knitr page by yihui talks about manipulation of the numeric value (scientific notation, digits after decimal points) which I have got covered.
The output hook inline can be used to style output from \Sexpr{}. This is as simple as
knit_hooks$set(inline = function(x) { sprintf("\\textbf{%s}", x)})
Just define an arbitrary function that takes an argument x and returns the string to be printed. In this example I used \textbf to make the output bold, but this can be extended to any LaTeX commands.
In this answer, Yihui suggests an improvement that still takes the default inline hook into account. This ensures rounding as usually performed by the default hook:
hook_inline <- knit_hooks$get('inline')
knit_hooks$set(inline = function(x) { sprintf("\\textbf{%s}", hook_inline(x))})
In the knitr package I like the kable function. It gives a nice layout of tables and data frame like objects even as it is called from within an R code chunk. Now I want to do the same thing with a character value. Is there a function that gives a kable-like output ("kprint") that can be formated?
knitr::kable() # exists for tables
knitr::kprint() # does a function like this exists for character values?
This is what I get now:
print("character value") # within the R Chunk
Output in generated report:
## [1] "character value"
And this is what I want, just:
character value
EDIT cat("character value") is not the solution I am looking for because I don't want an R output anymore, but just a plain text.
There are two things to do to get a "raw" character string (without any formatting or additional output like [1]) from R to TEX:
Use the chunk option results = "asis" to instruct knitr not to modify the output.
Use cat instead of print because print adds the lenght of the vector and quotes to the output.
In this context, inline output using \Sexpr{} might be useful because values in \Sexpr{} are by default printed "as they are": \Sexpr{myoutput}.
As there was the question of how to format the output in the comments, here some options:
Add LaTeX to the text you pass to cat: cat("\\emph{foo}"). Don't forget to escape \ by an additional \.
Do the same thing as above, but use a function to do the "dirty work":
makeItNiceR <- function(x) {
return(paste("\\fbox{\\texttt{", x, "}}"))
}
cat(makeItNiceR("foo bar is nice"))
(Note that we could use cat inside makeItNiceR to save some typing, but this makes the function less flexible and we cannot use it in combination with \Sexpr{} anymore.)
Manually add LaTeX formatting commands around \Sexpr{}:
Add formatting to \emph{\Sexpr{myoutput}} directly in LaTeX.
Combine makeItNiceR and \Sexpr{} to get nicely formatted output from \Sexpr{}:
\Sexpr{makeItNiceR(paste(myoutput, "is nice"))}
The following minimal examples demonstrates the usage of all code snippets from above:
\documentclass{article}
\begin{document}
<<results = "asis">>=
makeItNiceR <- function(x) {
return(paste("\\fbox{\\texttt{", x, "}}"))
}
myoutput <- "slim"
cat("foo")
cat("\\emph{foo}")
cat(makeItNiceR("foo bar is nice"))
#
\paragraph{Outside of chunk:} ~\\
\Sexpr{myoutput} \\
Add formatting to \emph{\Sexpr{myoutput}} directly in LaTeX. \\
\Sexpr{makeItNiceR(paste(myoutput, "is nice"))}
\end{document}
I'm working on a document in R, with knitr to pdflatex and am using the extended version of toLatex from memisc.
When I'm producing a table with cut intervals however, the square brackets are not sanitised and the pdflatex job errors because of the existence of [.
I tried putting sanitize=TRUE in the knitr chunk code, but this only works for tikz.
Previously, I have used gsub and replaced the string in the R object itself which is rather inelegant. I'm hoping someone could point me in the direction of a nuance of memisc or knitr that I'm missing or another function/method that would easily handle latex special characters.
Example
library("memisc")
library("Hmisc")
example<-data.frame(cbind(x=1:100,y=1:100))
example$x<-cut2(example$x,m=20)
toLatex(example)
UPDATE
Searching SO I found a post about applying latexTranslate with apply function, but this requires characters so I would have to unclass from factor to character.
I found another SO post that identifies the knitr:::escape_latex function however, the chunk then outputs the stuff as markup instead of translating it (using results='asis') or produces an R style table inside a code block (using results='markup'). I tried configuring it as a hook function in my parent document and it had the effect of outputting all the document contents as markup. This is a brand new area for me so I probably implemented it incorrectly.
<<setup,include=FALSE>>=
hook_inline = knit_hooks$get('inline')
knit_hooks$set(inline = function(x) {
if (is.character(x)) x = knitr:::escape_latex(x)
hook_inline(x)
})
#
...
<<tab-example,echo=FALSE,cache=TRUE,results='asis',sanitize=TRUE,inline=TRUE>>=
library("Hmisc")
library("memisc")
example<-data.frame(cbind(x=1:100,y=1:100))
example$x<-cut2(example$x,m=20)
toLatex(example)
#
According to #yihui this is the wrong way to go
UPDATE 2
I have created a gsub wrapper which will escape percentages etc, however the [ symbol still pushes latex into maths mode and errors.
Courtesy of folks on the tex SE, a [ directly after a line break(\\) is considered an entry into math-mode. It is very simple to prevent this behaviour by adding {} into the output just before a [. My function looks like:
escapedLatex<-function (df = NULL)
{
require("memisc")
gsub(gsub(x = toLatex(df, show.xvar = TRUE), pattern = "%",
replacement = "\\%", fixed = TRUE), pattern = "[", replacement = "{}[",
fixed = TRUE)
}
I'd be very happy to see any alternative, more elegant solutions around and will leave it open for a few days.