Dynamic references to figures in a R comment within Sweave document - r

I would like to find a way to use the LaTeX \ref{} markup to comment in the R code within a Sweave .Rnw file. Here are two examples, one in print
http://cm.bell-labs.com/cm/ms/departments/sia/project/nlme/UGuide.pdf
and one to use to work with:
The .Rnw file
% File: example.Rnw
\documentclass{article}
\usepackage{fullpage}
\usepackage{graphics}
\usepackage{Sweave}
\usepackage[margin = 10pt, font=small, labelfont={bf}]{caption}
\begin{document}
Here is an example file to show what I want to do. I would like to figure out how to use the \LaTeX\ reference command to reference a figure being generated by R code. Note in the R code, in a comment there is a reference to the figure, but of course the output file shows a verbatim copy of the \LaTeX\ markup. Does anyone know how to get something for Figure \ref{fig2}?
<< example plot >>=
library(reshape)
library(ggplot2)
n <- 100
lambda <- 1 / 3
x <- seq(0, qexp(0.999, rate = lambda), length = n)
q1.a <- data.frame(x = x,
f = dexp(x, rate = lambda),
F = pexp(x, rate = lambda))
q1.a <- melt(q1.a, id.vars = 'x')
g <- ggplot(q1.a) + # Produces \ref{fig1}
aes(x = x, y = value) +
geom_line() +
facet_wrap( ~ variable, scale = "free_y")
ggsave(g, filename = "example1.jpeg")
#
\begin{figure}[h]
\centering
\includegraphics[width = 0.48\textwidth]{./example1}
\caption{Exponential Distribution based plots.}
\label{fig1}
\end{figure}
Here is more of what I would like to see:
<< example plot 2 >>=
ggsave(g + geom_point(), filename = "example2.jpeg") # Produces Figure 2
#
\begin{figure}
\centering
\includegraphics[width = 0.48\textwidth]{./example2}
\caption{Exponential Distribution based plots with points and lines.}
\label{fig2}
\end{figure}
\end{document}
and the pdf is build with the R commands
Sweave(file = 'example.Rnw',
engine = "R",
keep.source = 'TRUE',
echo = 'TRUE',
results = 'verbatim')
tools::texi2dvi(file = "example.tex",
pdf = TRUE,
clean = TRUE)
Any insight on how do this would be great.

Here is one way to solve this issue by redefining the Sinput environment in which source code is wrapped by Sweave. By default, it is a simple verbatim environment which is not processed by latex for tokens. The trick is to redefine it to use the alltt environment which allows some tokens to be parsed inside the alltt environment. Note that this might lead to unwanted side effects that I am not aware of, so use with caution!
Here is a reproducible example that works. If you compile it, you will generate a file where ref{fig1} is replaced by the figure number.
\documentclass{article}
\usepackage{Sweave}
\usepackage{alltt}
\renewenvironment{Sinput}{\begin{alltt}}{\end{alltt}}
\begin{document}
In this document, we will create a plot using `R`, and reference its position in
the source code.
<<produce-plot, results = hide>>=
pdf('example1.pdf')
plot(1:10, 1:10) # Produces Figure \ref{fig1}
dev.off()
#
\begin{figure}
\includegraphics{example1.pdf}
\caption{Figure 1}
\label{fig1}
\end{figure}
\end{document}

Related

ggplot2 does not show the graph in Latex (knitr)

I have an issue with knitr and ggplot2 in Latex. I am trying to create a dynamic document with knitr. All my plots are in ggplot2. Hear me out:
I created the Latex document
I opened it in R Studio and saved the TEX file as RNW file. Global and Project options: knitr.
I pasted the R script there like:
<<echo=FALSE>>=
knitr::opts_chunk$set(fig.path='graphs/',
echo=FALSE, warning=FALSE, message=FALSE)
#
<<>>=
library(ggplot2)
library(tidyverse)
#
<<plot1>>=
my_data1 <- read.csv(file.choose(), header=TRUE, sep=",")
plot1 <- ggplot(data=my_data1, aes(x = pos , y = sum)) +
geom_line(colour = 'black', size = 1) +
scale_y_continuous(trans = 'log10', limits = c(1,100)) +
theme_classic() +
labs (x = 'axis_name1', y = 'axis_name2') +
coord_cartesian(xlim = c(1219890,1220102)) +
#
Everything is going well, except the graph does not show when I press 'Compile PDF' or in the graphs directory. However when I select only the R code and run it everything is fine(as long as I add print()). I managed to use TikZ which works just fine but without creating a dynamic document. I thought it was possible to output the plot directly in the PDF document but for some reason ggplot2 does not work. Is there something that I am missing?
Thank you.

R sweave generating only .eps

I'm using R sweave (*.Rnw) and want to generate only plotname.eps.
\documentclass{article}
\begin{document}
\SweaveOpts{concordance=TRUE}
\SweaveOpts{eps=TRUE}
<<plotname, fig=TRUE, echo=F, prefix=F>>=
ggplot(data=data, aes(x = day, y = outside_act))
#
\end{document}
When I compile this code, three plots are generated: plotname.eps and plotname.pdf.
How can I suppress R sweave from generating plotname.pdf? (I only need plotname.eps and I don't want R sweave to run this chunk an additional times.)
You can use \SweaveOpts{eps=TRUE, pdf=FALSE}. For full details on the options available, run vignette("Sweave") in the R console.
However, if all you want is the EPS file and not the document, you can just generate it directly, using
setEPS()
postscript("filename.eps")
ggplot(data=data, aes(x = day, y = outside_act))
dev.off()
in an R script.

ggplot2 image not showing up in pdf from Rmd

Sort of new to R markdown. I define a function that makes a plot with ggplot2 in a separate .R file:
heatMapDevRatio <- function(glmnet_obj_list,alpha_seq,
plot_name){
grid <- matrix(NA,nr=1,ncol=3)
colnames(grid) = c('alpha','lambda','dev.ratio')
for(idx in 1:length(glmnet_obj_list)){
alpha = getAlpha(names(glmnet_obj_list)[idx])
temp_df = data.frame(alpha=alpha,
lambda=glmnet_obj_list[[idx]]$lambda,
dev.ratio=glmnet_obj_list[[idx]]$dev.ratio)
grid = rbind(grid,temp_df)
}
grid = grid[-1,]
ggplot(data = grid, aes(lambda, alpha)) +
geom_raster(aes(fill = dev.ratio), interpolate = TRUE) +
ggtitle(plot_name) +
xlab(expression(~lambda)) +
ylab(expression(~alpha))
}
Anyway, the function runs fine-- the output goes to the standard graphics device if I run it in interactive session, or wherever I direct it if use the function in a script.
The problem is when I run the function in an Rmd file after source()-ing the file with the function definition.
```{r heatmap 10yr,eval=T,echo=F,fig.height=4,fig.width=4,fig.cap='lkjafkd'}
heatMapDevRatio(fitted_mods_20yr[2:10],alpha_seq,'adfasfd')
```
The export to pdf works, but on the pdf I just have a reference to some weird directory that doesn't seem to exist after execution-- where the figure should be, I have this text:
![lkjafkd](cox_summary[exported]_files/figure-latex/heatmap 10yr-1.pdf)
Should I just write the image to a file and include it, or should I be redirecting the graphics output? I thought it should just work.
Do you think the problem is the command I'm using to weave?
Rscript -e "rmarkdown::render('cox_summary.Rmd', output_format = 'pdf_document', output_file = 'cox_summary[exported].pdf')"

knitr: cannot create a figure with utf-8 character

The following is my .Rnw file:
\documentclass{article}
\begin{document}
<<myChunk>>=
options(warn = 2)
library(ggplot2)
library(directlabels)
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
BodyWeight$temp[BodyWeight$temp == "4"] <- "HI₂"
p <- qplot(Time,weight,data=BodyWeight,colour=temp,geom="line")
direct.label(p,"first.qp")
#
\end{document}
The following is how I call knitr from R:
library(knitr)
# I have tryied this but doesn't make difference:
# pdf.options(encoding='ISOLatin2.enc')
knit("mwe_knitr.Rnw")
I get following as output:
> knit("mwe_knitr.Rnw")
processing file: mwe_knitr.Rnw
|...................... | 33%
ordinary text without R code
|........................................... | 67%
label: myChunk
Quitting from lines 5-13 (mwe_knitr.Rnw)
Error in grid.Call(L_convert, x, as.integer(whatfrom), as.integer(whatto), :
(converted from warning) conversion failure on 'HI₂' in 'mbcsToSbcs': dot substituted for <e2>
I tried solutions with encoding, such as posted here:
Rhtml: Warning: conversion failure on '<var>' in 'mbcsToSbcs': dot substituted for <var>
(I note in comment above exactly where I try the solution to that problem) but it did not seem to change nothing for me.
I am using R 3.3.1 and knitr package 1.13 on Ubuntu.
It looks like using the cairo_pdf device resolves this issue. In the setup chunk below, I set the device option to the cairo_pdf device (that's the line that begins option(device = ...) and the global chunk option dev to default to "cairo_pdf" (in the line that begins knitr::opts_chunk$set(...). This approach is discussed in the knitr documentation (see the section Encoding of Multibyte Characters) and in Issue #436.
I've made a few other changes:
Instead of "hard-coding" "HI₂" I've used the Unicode symbol for the subscripted 2, "\U2082".
Changed the plot call to "standard" ggplot rather than qplot.
Changed from calling directlabels after making the plot to calling geom_dl to add direct labels within the "standard" ggplot workflow.
Set the fontfamily within geom_dl. I found that the subscript 2 was rendered with some font families, but not others.
Changed the warn option to zero (the default) so that warnings won't be turned into errors. I just did this while I was testing the code, but it can, of course, be set back to 2 if desired.
The chunk myChunk1a creates the plot. The chunk myChunk1b creates basically the same plot, but in multiple versions, each using a different font family. In these versions, you can see that the subscript 2 is rendered with some font families, but not others. I'm not sure what determines this and the results may be different on your system.
\documentclass{article}
\begin{document}
<<setup, include=FALSE>>=
options(warn = 0)
options(device = function(file, width = 7, height = 7, ...) {
cairo_pdf(tempfile(), width = width, height = height, ...)
})
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE, dev="cairo_pdf")
#
<<myChunk>>=
library(ggplot2)
library(directlabels)
library(gridExtra)
library(dplyr)
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
BodyWeight$temp[BodyWeight$temp=="4"] = "HI\U2082"
# Change first value so that HI2 label is easily visible
BodyWeight$weight[BodyWeight$temp=="HI\U2082" & BodyWeight$Time==1] = 350
#
<<myChunk1a, fig.height=5>>=
ggplot(BodyWeight, aes(Time, weight, colour=temp)) +
geom_line() +
geom_dl(method=list("first.qp", fontfamily="Helvetica", cex=1), aes(label=temp)) +
theme_bw() +
ggtitle("Helvetica") +
guides(colour=FALSE)
#
<<myChunk1b, fig.height=11>>=
# Create several plots, each demonstrating a different font family for the labels
grid.arrange(grobs=lapply(c("Helvetica","Courier","Palatino","Times","Serif"), function(f) {
ggplot(BodyWeight, aes(Time, weight, colour=temp)) +
geom_line() +
geom_dl(method=list("first.qp", fontfamily=f, cex=1), aes(label=temp)) +
labs(x="") +
theme_bw() +
theme(plot.margin=unit(c(0,0,0,0), "lines"),
text=element_text(size=9)) +
ggtitle(f) +
guides(colour=FALSE)
}), ncol=1)
#
<<myChunk2, fig.height=5>>=
data(BodyWeight,package="nlme")
BodyWeight$temp <- as.character(BodyWeight$Rat)
# Change first value so that HI2 label is easily visible
BodyWeight$weight[BodyWeight$temp=="4" & BodyWeight$Time==1] = 350
# Set temp==4 to desired expression
BodyWeight$temp[BodyWeight$temp == "4"] <- paste(expression(HI[2]))
# Convert temp to factor to set order
BodyWeight$temp = factor(BodyWeight$temp, levels=unique(BodyWeight$temp))
qplot(Time, weight, data=BodyWeight, colour=temp, geom="line") +
guides(colour=FALSE) +
geom_text(data=BodyWeight %>% group_by(temp) %>%
filter(Time == min(Time)),
aes(label=temp, x=Time-0.5, y=weight), parse=TRUE, hjust=1) +
theme_bw()
#
\end{document}
Here's what the plot from myChunk1a looks like:

Modify external R script in a knitr chunk

I'm wondering if it's possible to hook into the code in an external R script that is read by knitr.
Specifically, say that you have the following R file
test.R
## ---- CarPlot
library(ggplot2)
CarPlot <- ggplot() +
stat_summary(data = mtcars,
aes(x = factor(gear),
y = mpg
),
fun.y = "mean",
geom = "bar"
)
CarPlot
Imagine that you wanted to use this graph in multiple reports, but in one of these reports you want the graph to have a title and in the other report you do not.
Ideally, I would like to be able to use the same external R script to be able to do this so that I do not have to make changes to multiple R files in case I decide to change something about the graph.
I thought that one way to perhaps do this would be by setting the fig.show chunk option to hold—since it will "hold all plots and output them in the very end of a code chunk"—and then appending a title to the plot like so:
test.Rnw
\documentclass{article}
\begin{document}
<<external-code, cache=FALSE,echo=FALSE>>=
read_chunk('./test.R')
#
<<CarPlot,echo=FALSE,fig.show='hold'>>=
CarPlot <- CarPlot + ggtitle("Plot about cars")
#
\end{document}
This, however, does not work. Although the plot is printed, the title that I tried to append does not show up.
Is there some way to do what I would like to do?
You don't want to show the plot created by test.R, so you should set fig.show = 'hide' or include = FALSE for that chunk:
<<external-code, cache=FALSE,echo=FALSE,fig.show = 'hide'>>=
read_chunk('./test.R')
#
You do want to show the plot after modification, so you have to print it:
<<CarPlot,echo=FALSE>>=
CarPlot <- CarPlot + ggtitle("Plot about cars")
CarPlot
#
fig.show = 'hold' is used if you have a large code chunk that prints a plot in the middle, but you don't want the plot to show in your document until the end. It doesn't apply to this case.

Resources