Knitr ignoring fig.pos?
The chunk option fig.pos
is only used when knitr thinks it has to write out a LaTeX figure
environment instead of pure Markdown ![]()
, and it writes LaTeX only when a figure caption (fig.cap
) is specified, and at least one of these options has been specified: fig.align
, out.width
, out.extra
. If you want to force knitr to write LaTeX code for figures and use fig.pos
, you may set the chunk option out.extra = ''
.
How to hold figure position with figure caption in pdf output of knitr?
As Yihui mentioned in his answer (Figure position in markdown when converting to PDF with knitr and pandoc), we cannot expect too much about formatting from mardown. To workaround this problem, just write some R scripts to replace htbp
to H
.
Compared with knit
from knitr package, I found render
from rmarkdown is better to export a tex
file. Just remember to add keep_tex: yes
in the yaml header of your rmarkdown file.
library(rmarkdown)
render('filepath.Rmd')
x <- readLines('filepath.tex')
pos <- grep('begin\\{figure\\}\\[htbp\\]', x)
x[pos] <- gsub('htbp', 'H', x[pos])
writeLines(x, 'filepath.tex')
tools::texi2pdf('filepath.tex', clean = TRUE) # gives foo.pdf
file.remove('filepath.tex')
Figure position in markdown when converting to PDF with knitr and pandoc
I'm not aware of such an option for pandoc
to set the floating option of figures when converting a Markdown document to LaTeX. If you choose Markdown for its simplicity, you should not expect too much power from it, even with powerful tools like pandoc
. Bottom line: Markdown is not LaTeX. It was designed for HTML instead of LaTeX.
Two ways to go:
use the Rnw syntax (R + LaTeX) instead of Rmd (R Markdown) (examples); then you will be able to use the chunk option
fig.pos='H'
after you\usepackage{float}
in the preamble; in this case, you have full power of LaTeX, and pandoc will not be involvedhack at the LaTeX document generated by pandoc, e.g. something like
library(knitr)
knit('foo.Rmd') # gives foo.md
pandoc('foo.md', format='latex') # gives foo.tex
x = readLines('foo.tex')
# insert the float package
x = sub('(\\\\begin\\{document\\})', '\\\\usepackage{float}\n\\1', x)
# add the H option for all figures
x = gsub('(\\\\begin\\{figure\\})', '\\1[H]', x)
# write the processed tex file back
writeLines(x, 'foo.tex')
# compile to pdf
tools::texi2pdf('foo.tex') # gives foo.pdf
If you do not like these solutions, consider requesting a new feature to pandoc on Github, then sit back and wait.
Internationalization R knitr Figure caption label
You can actually include LaTeX code directly within the Rmd file to alter the settings.
As this answer explains, names like "Figure" and "Contents" are stored in macros like \figurename
and \contentsname
. To change them, you have to change the definition of the respective macros using \renewcommand
within your preamble:
\renewcommand{\figurename}{Fig.}
\renewcommand{\contentsname}{Table of Contents}
Here's a list of the "name macros" (and their default meaning) defined by the LaTeX standard classes article
, book
, and report
:
\abstractname
[onlyarticle
,report
]: Abstract\appendixname
: Appendix\bibname
[onlybook
,report
]: Bibliography\chaptername
[onlybook
,report
]: Chapter\contentsname
: Contents\figurename
: Figure\indexname
: Index\listfigurename
: List of Figures\listtablename
: List of Tables\partname
: Part\refname
[onlyarticle
]: References\tablename
: Table
Here is a MWE for your scenario:
---
output:
pdf_document: default
---
\renewcommand{\figurename}{YOUR LABEL}
\renewcommand{\tablename}{TABLE LABEL}
```{r Table, echo =FALSE}
knitr::kable(iris[1:5,], caption = "A table")
```
```{r pressure, echo=FALSE, fig.cap="Test Caption"}
plot(pressure)
```
Alternative Approach
The fantastic package bookdown expands a lot on the basics of RMarkdown and knitr. One thing the package allows you to set internalisation, as explained here.
knitr plots, labels, and captions within one chunk
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}
Related Topics
Transparent Equivalent of Given Color
Model.Matrix() with Na.Action=Null
Polygons Nicely Cropping Ggplot2/Ggmap at Different Zoom Levels
R Scoping: Disallow Global Variables in Function
Defer Code to End of Document in Knitr
Main Title at the Top of a Plot Is Cut Off
Ctree() - How to Get the List of Splitting Conditions for Each Terminal Node
Install the Package That Has Been Removed from the Cran Repository Easily
Conditional Rolling Mean (Moving Average) on Irregular Time Series
How to Change a Single Value in a Data.Frame
How to Define a Vectorized Function in R
Center-Align Legend Title and Legend Keys in Ggplot2 for Long Legend Titles
Keeping Zero Count Combinations When Aggregating with Data.Table
How to Plot Logit and Probit in Ggplot2
Apply() Is Slow - How to Make It Faster or What Are My Alternatives
Order and Color of Bars in Ggplot2 Barplot
Find Overlapping Dates for Each Id and Create a New Row for the Overlap