How can I suppress and capture knitr chunk ouput? - r

In a knitr document, I am calling an external code chunk which generates a ggplot2 object similar to the following:
# file.R
# ---- create_plot ----
library(ggplot2)
data(mtcars)
gg <- ggplot(mtcars, aes(mpg, cyl)) + geom_point()
gg
In my document (Flexdashboard Rmd, specifically):
# dashboard.Rmd
```{r setup}
knitr::read_chunk("plot.R")
```
```{r create_plot}
```
I would like to call this chunk and suppress the printing of the gg object, allowing me to do some tweaks to the object (title, colors, etc.) and display the plot later in my document. I've tried results='hide' when calling the chunk with no success. My desired document would be something like:
# dashboard.Rmd
```{r setup}
knitr::read_chunk("plot.R")
```
```{r create_plot, results='hide'}
```
```{r display_plot}
gg <- gg + labs(title = "Custom title")
gg
```
Is this possible without editing the external chunk to omit the final gg call?

You'll need to include = FALSE in the chunk option. This way, the code will run but not be included. I often do this when I run batch code using source(). Anyhow, give this a try:
```{r display_plot, include = FALSE}
gg <- gg + labs(title = "Custom title")
gg
```

Related

Stop ## quartz_off_screen showing in HTML report

My R Markdown files contain code to save PDF files e.g.
pdf(paste0("plots/filtering/", exp_name, "_umap.pdf"))
walk(list(p4, p5, p6, p7), print)
dev.off()
When I knit to HTML, I get the following printed as part of the HTML.
## quartz_off_screen
## 2
Is there a way to prevent this? I already have the knitr chunk options message and warning set to FALSE.
Best wishes,
Lucy
Wrap the the call to dev.off with invisible(...).
MWE
---
title: "Test"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(ggplot2)
library(purrr)
```
## R Markdown
```{r}
p1 <- ggplot(mtcars, aes(mpg, disp)) + geom_point()
p2 <- ggplot(mtcars, aes(mpg, disp, color = factor(vs))) + geom_point()
```
```{r}
pdf("mtcars.pdf")
walk(list(p1, p2), print)
invisible(dev.off())
```

Displaying the plots stored in a list, suppressing the names and indices from printing into console

I have a few ggplot2 plots stored in a named list, plt_list, and I would like to display the plots in R or Rmarkdown, without the names or list indices (e.g. [[1]]) to be displayed; just the plots. I have tried unname(plt_list), but the indices are printed into the console (or in Rmarkdown document, before each plot). With invisible nothing is displayed. Is there any way to do this in R?
We can use walk from purrr to display in Rmarkdown
---
title: "Title"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r plot_create, echo = FALSE}
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(ggplot2))
suppressPackageStartupMessages(library(purrr))
p1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) + geom_col()
plt_lst <- list(p1 = p1, p2 = p1, p3 = p1)
```
```{r plots, echo = FALSE, results = 'asis'}
walk(plt_lst, print)
```
-output
If we are trying this in R console, a for loop should also work
for(i in seq_along(plt_lst)) plt_lst[[i]]

knitr cache and ggplot2::last_plot()

Is there a way of make it so that knitr caches stuff so that last_plot() works properly? For example this document:
---
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, cache = TRUE)
library(ggplot2)
```
```{r cars}
ggplot(mtcars, aes(hp, mpg)) +
geom_point()
```
The first value is `r last_plot()$data$mpg[1]`
The first time is generated, it will have one figure and the text "The first value is 21". But the second time, the last inline code will fail.

Why can't i use fig.cap - Latex through Sweave + Knitr

I'm very new to Latex, and I'm trying my way on creating a graph with a figure caption.
Now when I try to add fig.cap in the chunk heading (second chunk) I get the error
Latex error: Not in outer par mode
My code
<<echo = FALSE>>=
source("analysis.R")
repoData <- readRDS("data/repoData.rds")
a4width<- 8.3
a4height<- 11.7
#
\begin{figure}[h]
<<echo = FALSE, fig.width= a4width, fig.height=0.35*a4height>>=
G2(repoData)
#
\end{figure}
## ---- G2 ----
G2 <- function(df) {
# For inflation graph
plot <- ggplot(df, aes(x = Month, y = Percent)) +
geom_line(colour = "firebrick") +
xlab("") +
ylab("Repo rate") +
theme_classic() +
theme(axis.title.y = element_text(vjust = 1))
return(plot)
}
Why does this happen and how can this be resolved?
You should omit the \begin{figure} (not shown in your MWE) and \end{figure} from your Sweave file; when you specify fig.cap they are generated automatically by knitr (and redundantly, in the case of your MWE, leading to the error).
If you need to specify other LaTeX figure options, see the "Plot" section of the knitr chunk options documentation: in particular, if you want to use position "h", use fig.pos="h" in your chunk options, as indicated by
fig.pos: (''; character) a character string for the figure position arrangement to be used in \begin{figure}[fig.pos]

subfigures stacked vertically with knitr

I am trying to put two subfigures stacked vertically rather than side-by-side using knitr in a Latex document. In Latex, I usually do this by putting a '\par' command between two subfloats that need to be stacked op top of one another, but I don't know how to pass that command on to knitr.
I've only been able to find one topic on this, Subfigures or Subcaptions with knitr?. The example given by Yihui puts the figures side by side. The final answer in that thread achieves my goal, but using quite a bit of hacking, so I'm wondering whether there's a simple way to pass this command to knitr directly?
MWE:
\documentclass[a4paper]{article}
\usepackage[font=footnotesize]{subfig}
\begin{document}
<<GeneratePlot>>=
library(ggplot2)
library(tikzDevice)
P1 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_line()
P2 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_point()
#
<<fig1,eval=TRUE,echo=FALSE,dev='tikz', fig.width=6, fig.height=3, out.width='1\\textwidth', fig.cap='Two figures', fig.subcap=c('Top','Bottom'), fig.show='asis', fig.pos='!htpb', fig.align='center', dependson='GeneratePlot'>>=
P1
P2
#
\end{document}
I've also tried creating the plot object in the same chunk as the output, but that yields the same result and in my original document the plot objects are generated as part of a larger chunk, so it will have the same structure as the MWE.
You can do that with the non-CRAN package oaReporting.
\documentclass[a4paper]{article}
\usepackage{float}
\usepackage{subcaption}
\begin{document}
<<setup, include=FALSE>>=
knitr::opts_chunk$set(fig.path="figures/")
library(oaReporting)
#
<<GeneratePlot>>=
library(ggplot2)
P1 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_line()
P2 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_point()
path1 <- createPlot(P1, file="./figures/P1.pdf")
path2 <- createPlot(P2, file="./figures/P2.pdf")
captions <- c("P1", "P2")
#
<<results="asis", fig.keep="none">>=
insertFigures(paths = c(path1, path2), captions=captions,
generalCaption = "P1 and P2",
generalLabel = "fig:P1andP2",
posMultipleFig = "H",
nCol = 1,
width = 0.7)
#
\end{document}
This has been officially supported in knitr 1.17.19 (current on Github). To add \par between the two subfigures, you can use the chunk option fig.sep = '\\par', e.g.,
\documentclass[a4paper]{article}
\usepackage[font=footnotesize]{subfig}
\begin{document}
<<GeneratePlot>>=
library(ggplot2)
library(tikzDevice)
P1 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_line()
P2 <- ggplot(data=mpg, aes(x=displ, y=hwy, colour=factor(cyl)))+
geom_point()
#
<<fig1, echo=FALSE,dev='tikz', fig.width=6, fig.height=3, out.width='1\\textwidth', fig.cap='Two figures', fig.subcap=c('Top','Bottom'), fig.show='asis', fig.pos='!htpb', fig.sep='\\par'>>=
P1
P2
#
\end{document}
Output:

Resources