Sometimes I get to make an R code chunk (in Sweave) which is longer then the margins of the page. Is there a way to force it to "go to the next line" once that happens?
Here is a simple example of that happening:
\documentclass[a4paper]{article}
\usepackage{Sweave}
\DefineVerbatimEnvironment{Sinput}{Verbatim} {xleftmargin=2em,
frame=single}
\DefineVerbatimEnvironment{Soutput}{Verbatim}{xleftmargin=2em,
frame=single}
\title{Sweave with boxes}
\begin{document}
\maketitle
<<echo=FALSE>>=
options(width=60)
#
Here is an example of a code chunk followed by an output chunk,
both enclosed in boxes.
<<>>=
print(rnorm(99))
#
<<>>=
print("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
#
\end{document}
This is a difficult and extreme case, because you do not have spaces among those a's, so LaTeX may not be able to wrap the words. If you do have spaces, knitr will be able to produce the output with the long lines wrapped with tidy=TRUE, highlight=TRUE (so will Sweave, I think, if you set keep.source=FALSE).
Related
I can't get R/KnitR to create the LaTeX \label{} statement for a figure. The manual seems to indicate that a \label{} statement will be created by concatenating the string in fig.lp ("fig:" by default) with the label for the R-code chunk. I haven't been able to get this to work, however. No \label{} statement is created for the first figure created by knitting the MWE below. The second figure has it's label added with a workaround that I just discovered, putting the R chunk in a figure environment, and putting the \label tag after or inside the \caption tag.
\documentclass[12pt, english, oneside]{amsart}
\begin{document}
Figure \ref{fig:plot} doesn't have it's label.
<<plot>>=
plot(x=0, y=0)
#
Figure \ref{fig:plot2} has its label.
\begin{figure}
\caption{\label{fig:plot2}}
<<>>=
plot(x=1,y=1)
#
\end{figure}
\end{document}
Okay, I've found a workaround by putting the R chunk in a \begin{figure} . . .\end{figure} environment in LaTeX. I can create the label in that same environment. Still, I'd like to understand how Yihui intends for this to be handled with KnitR.
You need to set fig.cap = '' (or whatever you wish) to ensure that a figure environment is used in the latex document. (you may have noticed that the \begin{figure} ... \end{figure} is missing along with the \label{} component
eg
\documentclass[12pt, english, oneside]{amsart}
\begin{document}
See Figure \ref{fig:plot}.
<<plot, fig.lp="fig:", fig.cap = ''>>=
plot(x=0, y=0)
#
\end{document}
I would agree that the description from the website is less than clear as to this being necessary.
fig.env: ('figure') the LaTeX environment for figures, e.g. set fig.env='marginfigure' to get \begin{marginfigure}
fig.cap: (NULL; character) figure caption to be used in a figure environment in LaTeX (in \caption{}); if NULL or NA, it will be
ignored, otherwise a figure environment will be used for the plots in
the chunk (output in \begin{figure} and \end{figure})
Although the graphics manual is clear, and the reasoning makes sense
Figure Caption
If the chunk option fig.cap is not NULL or NA, the
plots will be put in a figure environment when the output format is
LATEX, and this option is used to write a caption in this environment
using \caption{}. The other two related options are fig.scap and
fig.lp which set the short caption and a prefix string for the figure
label. The default short caption is extracted from the caption by
truncating it at the first period or colon or semi-colon. The label is
a combination of fig.lp and the chunk label. Because figure is a float
environment, it can float away from the chunk output to other places
such as the top or bottom of a page when the TEX document is compiled.
If you were wishing to replicate a R session output, you wouldn't want the figures to float away from the line of code which defines how they were created.
I am producing a latex report which produces multiple plots in a dlply call. The dlply call is of course in a single chunk and in order to get labels and captions to change I am using a snippet from Steve Powell below. The approach works but it seems knitr doesnt quite format the output correctly. A simple example that demonstrates:
\documentclass{article}
\begin{document}
<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)
#
<<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("<<",figLabel,",fig.pos='ht',fig.cap='",capt,"'>>=\nplt\n#",sep=''))))
}
#
\end{document}
This almost works. The trouble is that knitr places the closing \caption brace outside the \label brace which can be seen in the snippet from the .tex file below:
\begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}
\color{fgcolor}
\begin{figure}[ht]
\includegraphics[width=\maxwidth]{figure/Figure1} \caption[Caption for fig]{Caption for fig. 1\label{fig:Figure1}}
\end{figure}
\end{knitrout}
latex can handle this if there are only a few figures like this but with larger numbers of plots, it starts to place them incorrectly.
I have also tried this with a
fig.cap=paste('testLoop',seq(1,20))
approach and get the same result.
Further clarification: I found this on wikipedia's Latex/Floats... page:
If you want to label a figure so that you can reference it later, you have to add the label after the caption (inside seems to work in LaTeX 2e) but inside the floating environment. If it is declared outside, it will give the section number.
The 'inside seems to work in LaTeX 2e' part caught my attention. It seems it works only because the error is ignored a number of times? I am using
LaTeX2e <2005/12/01>.
I think the bit of code is in hook_plot_tex function line 120 of hooks-latex.R:
fig2 = sprintf('\\caption%s{%s\\label{%s}}\n\\end{%s}\n', scap, cap,
paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env)
This would fix it?
fig2 = sprintf('\\caption%s{%s}\\label{%s}\n\\end{%s}\n', scap, cap,
paste(lab, if (mcap) fig.cur, sep = ''), options$fig.env)
Suggestions? I am not familiar with the github process...
Thanks!
Short answer is it seems to be a LaTeX issue caused by too many \includegraphics commands and no pagebreaks. Function to accomplish multiple figures with captions and labels from within loop (with credit to Steve Powell and Yihui):
plot.knit<-function(chunkLabel,#text for chunk label which is also used for figure file name
capt,#text for caption
plt)#plot object to be placed
{
cat(knit(text=(paste("<<",chunkLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\n#",sep=''))))
}
cat('\\newpage')#some sort of page break must be inserted along the way to keep latex from breaking.
This can be modified to add any of chunk options you would like.
Long Answer:
Here is what I did to get it to work. I downloaded knitr from github, made the suggested alteration above, compiled, and ran example. The altered code did not change the outcome. Further investigation of latex error took me to the LaTeX FAQ where it states:
The error also occurs in a long sequence of float environments, with no intervening text. Unless the environments will fit “here” (and you’ve allowed them to go “here”), there will never be a page break, and so there will never be an opportunity for LaTeX to reconsider placement. (Of course, the floats can’t all fit “here” if the sequence is sufficiently prolonged: once the page fills, LaTeX won’t place any more floats, leading to the error.
Techniques for resolution may involve redefining the floats using the float package’s [H] float qualifier, but you are unlikely to get away without using \clearpage from time to time.
So, I added
cat('\\clearpage')
after the plots are generated in each step of the loop. This resulted in no errors being thrown and the figures in correct locations. Also,
cat('\\newpage')
works and seems to do a better job at placing the figures 2 on a page in my actual document.
The working code:
\documentclass{article}
\begin{document}
<<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)
#
<<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("<<",figLabel,",fig.pos='h',fig.cap='",capt,"'>>=\nplt\n#",sep=''))))
cat('\\newpage')
}
#
\end{document}
Using knitr to create a pdf, codechunks break according to page breaks. Usually this is exactly what I want, but in some cases I would like to be able to avoid this. E.g. by making a code-chunk jump to the next page if it does not fit the current page. I would prefer if this could be done in a chunk option, I.E not using eg. \newpage etc.
The following is an example of a code-chunk that breaks. How do I avoid this?
\documentclass{article}
\usepackage[english]{babel}
\usepackage{lipsum}
\begin{document}
\lipsum[1-3] \textbf{The following chunk will break. How do I avoid this breaking? }
<<echo=TRUE>>=
(iris)[1:20,]
#
\end{document}
I left an empty environment knitrout in the knitr design for such purposes. You can redefine this environment to achieve what you want. There are many LaTeX environments that are non-breakable, such as a figure environment. Below I use the minipage environment as an example:
\documentclass{article}
\renewenvironment{knitrout}{\begin{minipage}{\columnwidth}}{\end{minipage}}
% alternatively, you can use `figure`
% \renewenvironment{knitrout}{\begin{figure}}{\end{figure}}
\begin{document}
\begin{figure}
\caption{One figure.}
\end{figure}
% placeholder
\framebox{\begin{minipage}[t][0.3\paperheight]{1\columnwidth}%
nothing
\end{minipage}}
<<echo=TRUE>>=
(iris)[1:20,]
#
\begin{figure}
\caption{Another one.}
\end{figure}
\end{document}
I would like to make an R code chunk (in Sweave) printed inside a framed box in the resulting pdf.
Is there an easy solution for doing that?
The short answer is that yes, there is an easy way. Just add the following lines, or something like them to the preamble of your Sweave document:
\DefineVerbatimEnvironment{Sinput}{Verbatim} {xleftmargin=2em,
frame=single}
\DefineVerbatimEnvironment{Soutput}{Verbatim}{xleftmargin=2em,
frame=single}
This works because the appearance of code (and output) chunks is controlled by the definition of the Sinput and Soutput environments. These are both Verbatim environments as provided by the LaTeX package fancyvrb. (Click here for a 73 page pdf describing the numerous options that fancyvrb provides).
A quick look in the file Sweave.sty reveals the default definition of those two environments:
\DefineVerbatimEnvironment{Sinput}{Verbatim}{fontshape=sl}
\DefineVerbatimEnvironment{Soutput}{Verbatim}{}
\DefineVerbatimEnvironment{Scode}{Verbatim}{fontshape=sl}
To change those definitions, just add \DefineVerbatimEnvironment statements of your own devising either: (a) at the end of the Sweave.sty file; or (b) at the start of your *.Snw document.
Finally, here's an example to show what this looks like in practice:
\documentclass[a4paper]{article}
\usepackage{Sweave}
\DefineVerbatimEnvironment{Sinput}{Verbatim} {xleftmargin=2em,
frame=single}
\DefineVerbatimEnvironment{Soutput}{Verbatim}{xleftmargin=2em,
frame=single}
\title{Sweave with boxes}
\begin{document}
\maketitle
<<echo=FALSE>>=
options(width=60)
#
Here is an example of a code chunk followed by an output chunk,
both enclosed in boxes.
<<>>=
print(rnorm(99))
#
\end{document}
knitr, a successor of Sweave, by default outputs all echoed R code in boxes, and also formats it to the margins. Other nice features include syntax coloring and PGF integration.
Sweave code of average complexity needs only minor if any adaptions to run with knitr.
I'm writing a Sweave document, and I want to include a small section that details the R and package versions, platofrms and how long ti took to evalute the doucment, however, I want to put this in the middle of the document !
I was using a \Sexpr{elapsed} to do this (which didn't work), but thought if I put the code printing elapsed in a chunk that evaluates at the end, I could then include the chunk half way through, which also fails.
My document looks something like this
%
\documentclass[a4paper]{article}
\usepackage[OT1]{fontenc}
\usepackage{longtable}
\usepackage{geometry}
\usepackage{Sweave}
\geometry{left=1.25in, right=1.25in, top=1in, bottom=1in}
\begin{document}
<<label=start, echo=FALSE, include=FALSE>>=
startt<-proc.time()[3]
#
Text and Sweave Code in here
%
This document was created on \today, with \Sexpr{print(version$version.string)} running
on a \Sexpr{print(version$platform)} platform. It took approx sec to process.
<<>>=
<<elapsed>>
#
More text and Sweave code in here
<<label=bye, include=FALSE, echo=FALSE>>=
odbcCloseAll()
endt<-proc.time()[3]
elapsedtime<-as.numeric(endt-startt)
#
<<label=elapsed, include=FALSE, echo=FALSE>>=
print(elapsedtime)
#
\end{document}
But this doesn't seem to work (amazingly !)
Does anyone know how I could do this ?
Thanks
Paul.
This works just fine for me:
\documentclass{article}
\usepackage{Sweave}
\begin{document}
<<label=start, echo=FALSE, include=FALSE>>=
startt<-proc.time()[3]
#
Text and Sweave Code in here
This document was created on \today, with
\Sexpr{print(version$version.string)}.
<<results=hide,echo=FALSE>>=
Sys.sleep(2) # instead of real work
#
More text and Sweave code in here
<<label=bye, include=FALSE, echo=FALSE>>=
endt<-proc.time()[3]
elapsedtime<-as.numeric(endt-startt)
#
It took approx \Sexpr{elapsedtime} seconds to process.
\end{document}
I had to remove the version string inside the \Sexp{} as I get an underscore with via x86_64 which then upsets LaTeX. Otherwise just fine, and you now get the elapsed time of just over the slept amount.
You could use either R to cache the elapsed time in a temporary file for the next run, or pass it to LaTeX as some sort of variable -- but you will not be able to use 'forward references' as the R chunks gets evaluated in turn.
btw you don't usually need print to evaluate variables R
\Sexpr{version$version.string}
works fine as well
Dirk's answer is almost perfect, but still doesn't let you put the answer half way through the document. I got quite frustrated thinking it should work, but realised that the code I had was opening the time file at the start of each run (and emptying it) and writing the empty result into my document, then putting the answer in the time file at the end !
I eventually did something similar but using R to only open and write the file at the end, which worked great !;
\documentclass[a4paper]{article}
\usepackage[OT1]{fontenc}
\usepackage{longtable}
\usepackage{geometry}
\usepackage{Sweave}
\geometry{left=1.25in, right=1.25in, top=1in, bottom=1in}
\begin{document}
<<label=start, echo=FALSE, include=FALSE>>=
startt<-proc.time()[3]
#
Text and Sweave Code in here
%
This document was created on \today, with \Sexpr{print(version$version.string)} running
on a \Sexpr{print(version$platform)} platform. It took approx \input{time}
sec to process.
More text and Sweave code in here
<<label=bye, include=FALSE, echo=FALSE>>=
odbcCloseAll()
endt<-proc.time()[3]
elapsedtime<-as.numeric(endt-startt)
#
<<label=elapsed, include=FALSE, echo=FALSE>>=
fileConn<-file("time.tex", "wt")
writeLines(as.character(elapsedtime), fileConn)
close(fileConn)
#
\end{document}