When I'm inserting long captions and the like in my R chunk header, it'd be nice to be able to split the header across multiple lines.
Is there any easy way to do this?
E.g.:
```{r, echo=FALSE, warning=FALSE,
fig.cap="Here is my really long caption. It'd be nice to split this and other portions across lines"}
print(plot(x=runif(100),y=runif(100)))
```
No, you cannot insert line breaks in chunk options. From the manual:
Chunk options must be written in one line; no line breaks are allowed inside chunk options
However, if you desperately want neat formatting in the editor you could take a detour via an additional variable, but this inflates the code quite a lot:
---
output:
pdf_document:
fig_caption: yes
---
```{r}
mycaption <- "This is my
very long caption
that spans over
several lines.
(in the editor)"
```
```{r, fig.cap = mycaption}
plot(1)
```
With the option eval.after it is even possible to define mycaption within the chunk that uses it as option value:
---
output:
pdf_document:
fig_caption: yes
---
```{r}
library(knitr)
opts_knit$set(eval.after = "fig.cap")
```
```{r, fig.cap = mycaption}
mycaption <- "This is my
very long caption
that spans over
several lines.
(in the editor)"
plot(1)
```
(I assume that the question is about how the code looks (in the editor) not about a line break in the output.)
As of knitr v1.35 (https://github.com/yihui/knitr/releases/tag/v1.35) you are able to write chunk headers across multiple lines.
The syntax is slightly different from typical rmarkdown chunk syntax.
To achieve your goal, you extend the rmarkdown chunk header into the comments of the chunk.
You'd rewrite your example as follows:
```{r}
#| echo=FALSE, warning=FALSE,
#| fig.cap="Here is my really long caption. It'd be nice to split this and other portions across lines"
print(plot(x=runif(100),y=runif(100)))
```
Admittedly, that doesn't help handle having a very long figure caption, and the recommendation by CL to put the figure caption in a variable is still a good idea.
But, the new syntax also allows you to use yaml syntax to specify the chunk options, and yaml allows for multiline strings. So you could do the following:
```{r}
#| echo: false
#| warning: false
#| fig.cap: >
#| Here is my really long caption. It'd be nice to
#| split this and other portions across lines
print(plot(x=runif(100),y=runif(100)))
```
Related
I just discovered the awesome Xaringan package, and I'd like my presentation to be as incremental as possible.
For instance, my introduction slide looks like this:
```{r intro1, echo=TRUE}
version$version.string #should give 3.6.1
```
--
```{r intro2, echo=TRUE}
class(iris)
```
--
```{r intro3, echo=TRUE}
dim(iris) #row, cols
```
--
```{r intro4, echo=TRUE}
colnames(iris)
```
Though, I find it tedious and not much readable to write it that way.
I tried this but it doesn't work:
```{r , echo=TRUE}
version$version.string
class(iris)
--
dim(iris)
colnames(iris)
```
Of course, this consider -- as code.
Is there a way to increment my slide from inside the code?
Yihui pretty much gave the answers in the comments but I elaborate here with one additional tweak which will ensure that the separator code (i.e. knitr::asis_output('\n--\n')) is not visible in the output (this is done by specifying the line number in which the separator appears in the chunk argument as below).
You can the separator code where you want to separate and just make sure the corresponding line number is not echo-ed.
---
output:
xaringan::moon_reader:
seal: false
---
```{r, echo = -4}
version$version.string
class(iris)
knitr::asis_output('\n--\n')
dim(iris)
colnames(iris)
```
Consider the following R Markdown document:
---
title: "Stack Overflow Question"
author: "duckmayr"
date: "6/21/2019"
output: pdf_document
header-includes:
- \usepackage{setspace}
- \doublespacing
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Here is some example text.
I want all the body text to be double-spaced,
but I want all echoed code from code chunks to be single spaced.
In other words, not this:
```{r}
## This code is double-spaced.
## I want it to be single spaced.
## How can I do that?
```
Is there a canned or relatively painless way to have all normal text double-spaced, but have all code echoed from code chunks single spaced? I tried consulting the guide to chunk options here, but couldn't quite find what I was looking for.
If you are outputting to pdf the most painless way might be adding some LaTeX commands to your Rmd document:
---
title: "Stack Overflow Question"
author: "duckmayr"
date: "6/21/2019"
output: pdf_document
header-includes:
- \usepackage{setspace}
- \doublespacing
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Here is some example text. I want all the body text to be double-spaced, but I
want all echoed code from code chunks to be single spaced. In other words, not
this:
\singlespacing
```{r}
## This code is double-spaced.
## I want it to be single spaced.
## How can I do that?
```
\doublespacing
Some additional body text. Nor hence hoped her after other known defer his.
For county now sister engage had season better had waited. Occasional mrs
interested far expression acceptance. Day either mrs talent pulled men
rather regret admire but. Life ye sake it shed. Five lady he cold in meet up.
Alternatively, you could define a new chunk option using knitr chunk hooks. For instance, you could include in the setup chunk:
```{r setup, include=FALSE}
hook_chunk = knitr::knit_hooks$get('chunk')
knitr::knit_hooks$set(chunk = function(x, options) {
regular_output = hook_chunk(x, options)
# add latex commands if chunk option singlespacing is TRUE
if (isTRUE(options$singlespacing))
sprintf("\\singlespacing\n %s \n\\doublespacing", regular_output)
else
regular_output
})
knitr::opts_chunk$set(echo = TRUE, singlespacing = TRUE)
```
Some useful references:
Hooks - Customizable functions to run before/after a code chunk, tweak the output, and manipulate chunk options
How to Create New Chunk Options in R Markdown
From R for Data Science:
To put multiple plots in a single row I set the out.width to 50% for
two plots, 33% for 3 plots, or 25% to 4 plots, and set fig.align =
"default". Depending on what I’m trying to illustrate ( e.g. show data
or show plot variations), I’ll also tweak fig.width, as discussed
below.
How do I put multiple plots on a single row, using the method described above? I could use a package such as patchwork, but the purpose of this post is to understand what's being described above. The R Markdown below doesn't generate what I'd expect, two 'pressure' plots on the same row.
---
title: "Untitled"
author: "April 2018"
date: "4/11/2019"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
Text
```{r pressure1, echo=FALSE, fig.width=6, fig.asp=0.618, out.width="50%", fig.align="default"}
plot(pressure)
plot(pressure)
```
```{r pressure2, echo=FALSE, fig.width=6, fig.asp=0.618, out.width="50%", fig.align="default"}
plot(pressure)
```
I’ve got no idea why your code (or rather, the code from R for Data Science) is not working. But plotting different data makes it work for me:
```{r pressure1, echo=FALSE, fig.width=6, fig.asp=0.618, out.width="50%", fig.align="default"}
plot(cars)
plot(pressure)
```
Alternatively, it seems to be enough to just specify different parameters, e.g.:
plot(pressure)
plot(pressure, main = '')
The fact that inconsequential changes fix the output indicates to me that this is a bug in RMarkdown.
That said, the easiest, most controlled way is to put par(mfrow = c(1, 2)) into the hunk directly before the plotting commands (or a ggplot2 solution such as faceting or {patchwork}).
Tweaking the alignment via the RMarkdown options can be tricky, due to spacing inserted by the conversion to HTML.
You need to specify fig.show = "hold" along with out.width, as you can see here: https://bookdown.org/yihui/rmarkdown-cookbook/figures-side.html
I would like to edit a single rmarkdown (Rmd) document with a list of "problems", each followed by its solution. Each solution may contain the results of the R console, but also some explaining (markdown and LaTeX formatted) text. Besides, I would like use knitr in 2 versions: with and without the solutions, changing the source as less as possible, and compiling.
I know that I can use a logical variable in order to conditionally evaluate R code and show plots and R output, but I don't know how to show/hide blocks of (markdown and LaTeX) formatted text, unless I put all that text into R character vectors, which seems hard for keeping things clean and readable.
I found this old question,
Conditionally display a block of text in R Markdown
where the solution was given for simple short text, which was included as an argument of the R print() function.
This other old question,
insert portions of a markdown document inside another markdown document using knitr
was for having a father document and child documents which were conditionally compiled, but I don't want to slice my document into so many pieces.
You could use the asis engine to conditionally include/exclude arbitrary text in knitr, e.g.
```{asis, echo=FALSE}
Some arbitrary text.
1. item
2. item
Change echo=TRUE or FALSE to display/hide this chunk.
```
But I just discovered a bug in this engine and fixed it. Unless you use knitr >= 1.11.6, you can create a simple asis engine by yourself, e.g.
```{r setup, include=FALSE}
library(knitr)
knit_engines$set(asis = function(options) {
if (options$echo && options$eval) paste(options$code, collapse = '\n')
})
```
If you want to include inline R expressions in the text, you will have to knit the text, e.g.
```{r setup, include=FALSE}
library(knitr)
knit_engines$set(asis = function(options) {
if (options$echo && options$eval) knit_child(text = options$code)
})
```
There is a way to hide parts of the document (including text and chunks): to comment them out with html comment marks.
And comment marks can be generated by R in a block according to a variable that can be set at the beginning of the document.
```{r results='asis', echo=FALSE}
if (hide) {cat("<!---")}
```
```{r results='asis', echo=FALSE}
if (hide) {cat("-->")}
```
And just to show a complete working example, in the example below the middle section of the document can be shown or hidden by setting the hide variable to FALSE or TRUE. That might be useful in case there are several sections to hide or show at once - for example, solutions of course problems.
---
title: "Untitled"
date: "15/10/2020"
output:
word_document: default
html_document: default
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
hide <- TRUE #TRUE to comment out part of the document, FALSE to show.
```
## Start
Always shown.
```{r}
hide
```
```{r results='asis', echo=FALSE}
if (hide) {cat("<!---")}
```
## To hide or not to hide
To be hidden or shown according to *hide* variable.
```{r}
"Also to be hidden according to 'hide' variable"
hist(rnorm(10))
```
```{r results='asis', echo=FALSE}
if (hide) {cat("-->")}
```
<!--
Never shown.
-->
## End
Always shown.
Just a caveat: in html output the hidden parts are kept as comments and can be seen just by viewing the source. On the other hand, PDF (LaTex) and Word outputs ignore html comments and the hidden parts aren't included in the knitted documents.
Therefore, when the hidden parts are supposed to be somehow confidential (e.g. exam solutions) PDF or Word output should be used instead of html.
For those looking for a solution when knitting to pdf through LaTex, the answer from #Pere won't work for you (because LaTex doesn't understand the <!--- --> pair as indicating a comment).
Below is one possible workaround:
---
output:
pdf_document
---
\newcommand{\ignore}[1]{}
```{r echo=FALSE}
include <- TRUE
```
```{r results='asis', echo=FALSE}
if(!include){cat("\\ignore{")}
```
Included bla bla
```{r results='asis', echo=FALSE}
if(!include){cat("}")}
```
```{r echo=FALSE}
include <- FALSE
```
```{r results='asis', echo=FALSE}
if(!include){cat("\\ignore{")}
```
NOT Included bla bla
```{r results='asis', echo=FALSE}
if(!include){cat("}")}
```
Jallen produced a solution for producing knitr plots, labels, and captions within one chunk - for Rnw files.
knitr plots, labels, and captions within one chunk
This works nicely for .Rnw but I can't make it work for .Rmd, don't see what is going wrong...
---
output:
pdf_document:
fig_caption: yes
fig_crop: no
---
```{r startup,echo=FALSE,results='hide',message=FALSE,tidy=FALSE,warning=FALSE,fig.keep='all',comment=NA}
require(knitr)
require(ggplot2)
opts_knit$set(progress = F, verbose = F)
opts_chunk$set(comment=NA,
tidy=FALSE,
warning=FALSE,
message=FALSE,
echo=FALSE,
dpi=600,
fig.width=6.75, fig.height=4, # Default figure widths
dev=c("pdf",'tiff'),
dev.args=list(pdf=list(NULL),tiff=list(compression='lzw')),
error=FALSE)
```
```{r plotloop,results='asis'}
for(x in seq(1,20)){
x1<-data.frame(x=seq(1,10),y=seq(1,10))
plt<-ggplot(data=x1,aes(x,y))+geom_point()
figLabel=paste('Figure',x,sep='')
capt<-paste('Caption for fig.',x)
cat(knit(text=(paste("```{r ",figLabel,",fig.pos='h',fig.cap='",capt,"'}\nplt\n```",sep=''))))
cat('\\newpage')
plot.knit function in knitr plots, labels, and captions within one chunk can be modified to account for the syntax of markdown as opposed to latex. plot.knit.md becomes
plot.knit.md<-function(chunkLabel,#text for chunk label which is also used for figure file name
capt,#text for caption
plt,
...)
{
cat(knit(text=knit_expand(text="```{r, {{chunkLabel}},eval=TRUE,fig.cap='{{capt}}',echo=FALSE}\nplt\n```"),
quiet=TRUE))
}
This works in the following markdown doc.
---
title: "plot.knit.md demo"
author: "Joel Allen"
date: "04/23/2015"
output:
html_document: default
pdf_document:
fig_caption: yes
---
This is an R Markdown document to demonstrate the generation of self-contained code chunks in a markdown file. It is particularly useful for situations where multiple plots are generated in a single code chunk allowing for dynamic label and caption support.
This example draws on
http://stackoverflow.com/questions/21685885/knitr-plots-labels-and-captions-within-one-chunk
in response to
https://stackoverflow.com/questions/27443019/knitr-plots-labels-and-captions-within-one-chunk-rmd-files
Items to note:
#. output pdf_document fig_caption option must be set to yes
#. plot.knit has been modified to plot.knit.md to account for the different syntax needed.
```{r, echo=FALSE,results='asis'}
plot.knit.md<-function(chunkLabel,#text for chunk label which is also used for figure file name
capt,#text for caption
plt,
...)
{
cat(knit(text=knit_expand(text="```{r, {{chunkLabel}},eval=TRUE,fig.cap='{{capt}}',echo=FALSE}\nplt\n```"),
quiet=TRUE))
}
require(ggplot2)
cars.p<-ggplot(cars,aes(x=speed,y=dist))+
geom_point()
plot.knit.md(chunkLabel="carsPlot",capt="this is a caption for the cars plot",plt=cars.p)
```
One thing to figure out though is the attachment of labels...