Can Sweave produce many pdfs automatically?
You can use something like a for
loop with a global variable changing, which controls which city you want to weave into the report; see the other post Run Sweave or knitr with objects from existing R session
The code will be like (suppose cities
is a character vector, and I use the knitr
package as an example because you can specify the filename of the output):
for (city in cities) {
knit('city_template.Rnw', output = paste('report_', city, '.tex', sep = ''))
}
Inside city_template.Rnw
, you have a chunk like
<<do-my-job>>=
make_plot(city, ...)
whatever(city, ...)
@
Then you will get a series of tex files named by the cities, and the rest of your job is to compile them to PDF (not possible for RStudio to compile multiple tex files, AFAIK, but it is trivial to do it in command line or in R with texi2dvi()
).
There is one thing you need to be careful -- you have to use a different figure prefix (the option fig.path
) for each output file, otherwise different cities can override each other's figure output. In knitr
, this can be done by like this:
<<setup, echo=FALSE>>=
opts_chunk$set(fig.path = paste('my-prefix-', city, sep = ''))
@
I believe this should be safe to produce many reports with a loop.
BTW, you can certainly achieve the same goal with Sweave; perhaps you will know why I developed knitr
later (this is off-topic, so I won't expand here).
Using loops with knitr to produce multiple pdf reports... need a little help to get me over the hump
You don't need to re-define the data in the .Rnw
file and I think the warning is coming from the fact that you are putting the output name together with Hospital
(the full vector of hospitals) rather than hosp
(the loop index).
Following your example, testingloops.Rnw
would be
\documentclass[10pt]{article}
\usepackage[margin=1.15 in]{geometry}
<<loaddata, echo=FALSE, message=FALSE>>=
subgroup <- df[ df$Hospital == hosp,]
@
\begin{document}
<<setup, echo=FALSE >>=
opts_chunk$set(fig.path = paste("test", hosp , sep=""))
@
Some infomative text about hospital \Sexpr{hosp}
<<plots, echo=FALSE >>=
for(ward in unique(subgroup$Ward)){
subgroup2 <- subgroup[subgroup$Ward == ward,]
# subgroup2 <- subgroup2[ order(subgroup2$Month),]
savename <- paste(hosp, ward)
plot(subgroup2$Month, subgroup2$Outcomes, type="o", main=paste("Trend plot for", savename))
}
@
\end{document}
and the driver R file would be just
## make my data
Hospital <- c(rep("A", 20), rep("B", 20))
Ward <- rep(c(rep("ICU", 10), rep("Medicine", 10)), 2)
Month <- rep(seq(1:10), 4)
Outcomes <- rnorm(40, 20, 5)
df <- data.frame(Hospital, Ward, Month, Outcomes)
## knitr loop
library("knitr")
for (hosp in unique(df$Hospital)){
knit2pdf("testingloops.Rnw", output=paste0('report_', hosp, '.tex'))
}
How to create multiple PDFs with different content from a single data frame?
From the question, I'm not entirely sure about the expected output, but there concept is clear. And although the task itself is quite simple, surprisingly many things can go wrong.
Code:
code.R
library(knitr)
library(ggplot2)
dir.create(path = "output/")
opts_knit$set(base.dir = "output/")
for(i in 1:nrow(mtcars)) {
filename <- rownames(mtcars)[i]
knit(input = "template.Rnw", output = paste0("output/", filename, ".tex"))
tools::texi2pdf(paste0("output/", filename, ".tex"), clean = TRUE)
file.copy(from = paste0(filename, ".pdf"), to = paste0("output/", filename, ".pdf"))
# file.remove(paste0(filename, ".pdf")) # this will DELETE filename.pdf from the current working directory (should be safe because we just created this file)
}
template.Rnw
\documentclass{article}
\begin{document}
<<>>=
ggplot(mtcars[i,], aes(x = cyl, y = disp) ) + geom_point()
@
\end{document}
- We need to set
base.dir
because the current working directory is one level above the directory where the document is created. This would lead to wrong figure paths: knitr produces the plots infigure/
but they should be inoutput/figure/
. Consequently, compilation will fail. - For some reason
knit2pdf
cannot compile the generated intermediate TEX file. Therefore I useknit
to produce a TEX file and thentools::texi2pdf
to compile this file to PDF.
Note how variables from code.R
are visible to the code in the template document. That's why i
can be used in template.Rnw
.
Figure numbers generated by Sweave/R and why only (PDF)LaTeX
Your example is not reproducible because we don't have the file apples.d
, so we can only guess why the plot goes wrong. Please see:
How to make a great R reproducible example?
on how to make a reproducible example.
Please note that Sweave
is not a functionality of Rstudio
or Tinn-R
, it is an R function (Sweave()
) that can be run from command line or with arguments from the R executable. This might be helpful to know if you are searching for information.
As for your questions:
- The names of plots always have the form
FILENAME-CHUNKLABEL.pdf
or eps, where the chunk label can be set as option to the Sweave chunk (it's the first argument). If you don't set a chunk name the plots will be enumerated. - You can use
eps
with the optioneps=true
. I am pretty sure that by default both eps and pdf are produced though. As for compiling, Sweave does not compile by itself, it creates a.tex
file that you can use in whatever way you want. In R 2.14 there is an option to run pdfLaTeX on the produced .tex file automatically,. The wayRstudio
andTinn-R
compile is probably by using an pdfLaTeX call after Sweave. You can do it manually if you want to do it differently. - Without a reproducible example we can only guess. What is going wrong? You could set the limits of the plot with the
xlim
andylim
arguments but that shouldn't be what is going wrong here.
Edit:
In response to edited question with data. First just a tip. This way of giving the data isn't the most useful way of doing it. We can of course reproduce this but it is much easier if you give the data in a way we can run immediately. e.g.:
test.frame<-data.frame(year=8:11, value= c(12050,15292,23907,33991))
As for the plot, you mean the labels on the y axis? This can be changed by omiting axes in the plot call and setting them manually with the axis()
function:
with(test.frame,plot(year,value,axes=FALSE))
axis(1)
axis(2,test.frame$value,las=1)
This does look a bit weird if the ticks aren't constantly distributed over the axis though. Better would be:
with(test.frame,plot(year,value,axes=FALSE))
axis(1)
axis(2,seq(10000,35000,by=5000),las=1)
sweave and ggplot2: no pdfs generated at all
qplot()
produces objects, not a graphic output. It might seem like it does when you run it, but that's because without assignment, R is automatically printing the output of qplot()
. To integrate it into Sweave, either wrap print()
around qplot()
, or assign the output of qplot()
to something, then wrap that in print()
.
...
<<fig = T, echo = F>>=
library(ggplot2)
x=rnorm(100)
p <- qplot(x)
print(p)
@
...
That should work. I use ggplot2
graphics in my sweave docs all the time.
Related Topics
Using Get() with Replacement Functions
Writing Robust R Code: Namespaces, Masking and Using the '::' Operator
Insert a Logo in Upper Right Corner of R Markdown PDF Document
How to Retrieve Outlook Inbox Emails Using R Rdcomclient
How to Set the Default Language of Date in R
Rolling Sum by Another Variable in R
Error in New.Session():Could Not Establish Session After 5 Attempts
Counting the Frequency of an Element in a Data Frame
How to Merge and Sum Two Data Frames
Remove Facet_Wrap Labels Completely
Split One Row into Multiple Rows
Why Use As.Factor() Instead of Just Factor()
Can Sweave Produce Many PDFs Automatically
Dplyr - Using Mutate() Like Rowmeans()
Plot.New Has Not Been Called Yet
Create Column with Grouped Values Based on Another Column