Wrapping figures generated in a knitr chunk when knitting to pdf - r

In a .Rmd document, I am generating multiple related figures (from a list) in a knitr chunk.
When knitting to html, those figures are wrapped properly and all visible.
When knitting to pdf, the figures are all one after the other and only the first two are visible (and half of the third). Here is some code that reproduces the issue:
---
title: "Example figure wrapping problem"
output:
pdf_document:
keep_tex: true
classoption:
landscape
---
# SK-N-SH plex panel {.tabset .tabset-fade}
```{r, echo=FALSE, message=FALSE}
knitr::opts_chunk$set(fig.width=6, fig.height=9, fig.show="hold", hightligh=TRUE, warnings=TRUE, error=FALSE, cache=FALSE, echo=FALSE, dpi=100)
```
```{r}
for (ii in 1:6) {
plot(1:3, 1:3, main=ii)
}
```
I figured that the problem comes from the generation of the .tex file, which contains this line:
\includegraphics{figure/unnamed-chunk-2-1.png}\includegraphics{figure/unnamed-chunk-2-2.png}\includegraphics{figure/unnamed-chunk-2-3.png}\includegraphics{figure/unnamed-chunk-2-4.png}\includegraphics{figure/unnamed-chunk-2-5.png}\includegraphics{figure/unnamed-chunk-2-6.png}
Adding line breaks every two includegraphics solves the problems:
\includegraphics{figure/unnamed-chunk-2-1.png}\includegraphics{figure/unnamed-chunk-2-2.png}
\includegraphics{figure/unnamed-chunk-2-3.png}\includegraphics{figure/unnamed-chunk-2-4.png}
\includegraphics{figure/unnamed-chunk-2-5.png}\includegraphics{figure/unnamed-chunk-2-6.png}
However it is obviously not practical as there are many more figures. I could also run sed 's/}\(\\includegraphics\)/}\r\1/g' on the file but it feels like uselessly complicating the compiling process.
Is there a native knitr or rmarkdown way to solve my problem.

If you specify fig.align="center" and fig.show="asis" in the code chunk it seems to work. For example
---
title: "Example figure wrapping problem"
output:
pdf_document:
keep_tex: true
classoption:
landscape
---
# SK-N-SH plex panel {.tabset .tabset-fade}
```{r, echo=FALSE, message=FALSE}
knitr::opts_chunk$set(fig.width=6, fig.height=9, fig.show="hold", hightligh=TRUE, warnings=TRUE, error=FALSE, cache=FALSE, echo=FALSE, dpi=100)
```
```{r fig.align="center",fig.show="asis"}
for (ii in 1:6) {
plot(1:3, 1:3, main=ii)
}
```
looks fine. It generates LaTeX code
\begin{center}\includegraphics{Untitled_files/figure-latex/unnamed-chunk-2-1} \end{center}
\begin{center}\includegraphics{Untitled_files/figure-latex/unnamed-chunk-2-2} \end{center}
etc.
which breaks up the figures. You can use fig.align="right" or fig.align="left" instead, but it's essential that you don't use fig.show="hold", or all the figures are wrapped together, and you return to the original problem.

Related

Extracting a list of LaTeX figure and caption labels from RMarkdown to copy into Overleaf

I am working with coauthors. We want to produce all figures and tables (including an appendix) in a single RMarkdown document but write the paper jointly in Overleaf (excellent for simultaneous editing, which we don't need for the statistical code).
Here is an example Rmd which knits to a pdf. (The pdf will be appended manually to the main paper.)
---
title: "Nice document"
output: pdf_document
date: '2022-08-12'
---
```{r}
library(kableExtra)
```
```{r pressure, echo=FALSE, fig.cap="\\label{fig:pressure} Nice caption."}
plot(pressure)
```
```{r echo=FALSE, fig.cap="\\label{fig:diffpressure} Better caption."}
kable(head(mtcars), longtable = T, booktabs = T, caption = "Cool table", label = "tab:carssummary")
```
\appendix
\setcounter{figure}{0}
\setcounter{table}{0}
\renewcommand{\thefigure}{S\arabic{figure}}
\renewcommand{\thetable}{S\arabic{table}}
```{r echo=FALSE, fig.cap="\\label{fig:diffpressure} Better caption."}
plot(pressure/3.5)
```
I want a extract a character vector from the Rmd that is the following:
\begin{figure}
\caption{empty}
\label{fig:pressure}
\end{figure}
\begin{table}
\caption{empty}
\label{tab:carssummary}
\end{table}
\appendix
\setcounter{figure}{0}
\setcounter{table}{0}
\renewcommand{\thefigure}{S\arabic{figure}}
\renewcommand{\thetable}{S\arabic{table}}
\begin{figure}
\caption{empty}
\label{fig:pressure2}
\end{figure}
I will then copy and paste this to the bottom of the Overleaf doc, enabling us to do the automated cross referencing with minimal hassle (and easy updating if and when the analysis output changes).
How can I extract that LaTeX code from the Rmd?
Assuming your markdown document is called test.rmd and you included the keep_tex: true option to the header
---
title: "Nice document"
output:
pdf_document:
keep_tex: true
date: '2022-08-12'
---
You can upload the test.aux file to overleaf and then include the cross-refs in your overleaf document with the xr-hyper package:
\documentclass{article}
\usepackage{xr-hyper}
\externaldocument{test}
\usepackage{hyperref}
\begin{document}
some cross-ref: \ref{fig:diffpressure}
\end{document}

RMarkdown size directives ignored for in-document chunk output when using html_notebook_output_html or kable

In an r notebook viewed in RStudio, I can have the following yaml, setup, r chunk, and text:
---
title: "R Notebook"
output:
html_notebook:
fig_height: 2
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(fig.height=2, fig.width=2, out.height=2, out.width=2)
```
```{r fig.height=2, fig.width=2, out.height=2, out.width=2}
rmarkdown::html_notebook_output_html(
"<div style='border:1px solid red'>hello</div>"
)
```
goodbye
Note the variety of ways I'm trying to establish the height for the html object. For the .nb.html file, this outputs just fine. 'Goodbye' is right after a red bordered 'hello'.
However, for the in-document output that follows immediately after the code chunk, the output is quite tall (I believe the default is 7 inches, and that's about what it seems to be), and certainly outsizes its contents. The size directives (fig.height, out.height) are ignored.
Is there a more appropriate way to set the size?
I ran into the issue when using kable:
```{r fig.height=2, fig.width=2, out.height=2, out.width=2}
knitr::kable(data.frame(col1 = c('hello')), 'html')
```
Though I don't think it's a kable issue, based on the first example, I believe it's an rmarkdown issue.

Code in Columns in RMarkdown presentation

Often when I include r code in a rmarkdown pdf presentation, I want to use the space of the whole slide and therefore want to present the code and the output side-by-side.
In pure LaTex I would go for \begin{columns}...\end{columns} and then include the code/output manually using lstlistings or some other code-highlighting library. But that proves tedious if I exceed a couple of code examples.
Now I want to use RMarkdown for the presentations and would like to achieve a similar result.
However, the following code throws an error:
## This is slide 1
\begin{columns}[t]
\begin{column}{0.5\textwidth}
```{r, eval=F}
plot(1:10)
```
\end{column}
\begin{column}{0.5\textwidth}
```{r, echo=F}
plot(1:10)
```
\end{column}
\end{columns}
Leaving out the knitr code-chunks and replacing them with text works.
I am aware that it has something to do with the pandoc engine (see here), but wanted to ask if anybody has found a way around this issue.
Well, I may should have looked with a wider focus.
Here is a solution that works for Python, but can easily be adapted to Rmarkdown: https://stackoverflow.com/a/26069751/3048453
I ended up with this code:
in header.tex
\newcommand{\columnsbegin}{\begin{columns}}
\newcommand{\columnsend}{\end{columns}}
in presentation.Rmd
---
title: "Two-column codes in RMarkdown"
author: "My Name"
date: "February 4, 2017"
output:
beamer_presentation:
includes:
in_header: header.tex
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Testslide with Columns
\columnsbegin
\column{.5\textwidth}
```{r, eval=F}
plot(mtcars[, 1:3])
```
\column{.5\textwidth}
```{r, echo=F}
plot(mtcars[, 1:3])
```
\columnsend
Which results in this

R markdown Page Breaks from Function

I am trying to break to a new page from a R markdown document that is calling a function to produce a set of graphics for each set of data (400+ pages in some cases). I am using LaTeX.
Any ideas? Here is a simple example that demonstrates some my challenge though it doesn't use a function to produce the output.
---
title: "Test Page Break"
output: pdf_document
---
```{r}
summary(cars)
cat("\\pagebreak")
print(cars)
```
Update #1:
My example didn't demostrate the use of a function within the code chunk. Here is a better example.
---
title: "Test Page Break"
output: pdf_document
---
```{r}
pr_w_pagebreak <- function() {
print(summary(cars))
cat("\\pagebreak")
print(cars)
}
pr_w_pagebreak()
```
The trouble you'll have with your chunks is that you want some results to appear as 'markup' and some to appear 'asis'. If you want to get the page break with the single block as you have it, you will need to do:
```{r, echo=-2}
summary(cars)
knitr::asis_output("\\pagebreak")
print(cars)
```
Otherwise, you'll have to do
```{r}
summary(cars)
```
\pagebreak
```{r}
print(cars)
```
And as Floo0 points out, you can get LaTeX code from the R chunks if you use results = 'asis', but you have to be careful because the following will not give you what you want.
```{r, results='asis'}
summary(cars)
cat("\\pagebreak")
print(cars)
````

knitr plots, labels, and captions within one chunk - .Rmd files

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...

Resources