knitr/rmarkdown/Latex: How to cross-reference figures and tables?

早过忘川 提交于 2019-11-26 10:26:17

问题


I\'m trying to cross-reference figures and tables in a PDF produced with knitr/rmarkdown. There are some questions on SO and tex.stackexchange (here and here, for example), that suggest the way to do this inline is to add \\ref{fig:my_fig}, where my_fig is the chunk label. However, when I try that in my rmarkdown document, I get ?? where the figure number should be. I\'d like to find out how to get cross-referencing to work properly.

A reproducible example is below. There are two files: the rmarkdown file plus a header.tex file that I\'ve included just in case it affects the answer (though I have the same problem whether I include the header.tex file or not).

In the rmarkdown file there are three cross-reference examples. Example 1 is a figure for which cross-referencing fails (?? is displayed instead of the figure number). There\'s also a second, commented-out attempt (based on this SO answer), where I try setting the figure environment, label, and caption with latex markup before and after the chunk, but this results in a pandoc error when I try to knit the document. The error is:

! Missing $ inserted.
<inserted text> 
                $
l.108 ![](testCrossRef_

Example 2 uses xtable and cross-referencing works. Example 3 uses kable and cross-referencing fails.

A screenshot of the PDF output is included at the bottom of this post.

rmarkdown file

---
title: | 
  | My Title  
author: | 
  | eipi10  
  | Department of Redundancy Department  
date: \"`r format(Sys.time(), \'%B %e, %Y\')`\"
output: 
  pdf_document:
    fig_caption: yes
    includes:
      in_header: header.tex
    keep_tex: yes
fontsize: 11pt
geometry: margin=1in
graphics: yes
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE, fig.height=2, fig.width=4)
```

# Example 1. Figure

This is a report. Take a look at Figure \\ref{fig:fig1}.  

```{r fig1, echo=FALSE, fig.cap=\"This is a caption\"}
plot(mtcars$wt, mtcars$mpg)
```

<!-- Now, let\'s take a look at this other plot in Figure \\ref{fig:fig2}. -->

<!-- \\begin{figure} -->
<!-- ```{r fig2, echo=FALSE} -->
<!-- plot(mtcars$cyl, mtcars$mpg) -->
<!-- ``` -->
<!-- \\caption{This is another caption} -->
<!-- \\label{fig:fig2} -->
<!-- \\end{figure} -->

# Example 2: `xtable`

Some more text. See Table \\ref{tab:tab1} below. 

```{r echo=FALSE, results=\"asis\"}
library(xtable)
print.xtable(
  xtable(mtcars[1:3,1:4], label=\"tab:tab1\", caption=\"An xtable table\"), 
  comment=FALSE)
```

# Example 3: `kable`

Some more text. See Table \\ref{tab:tab2} below. 

```{r tab2, echo=FALSE}
library(knitr)
kable(mtcars[1:3,1:4], caption=\"A `kable` table\")
```

header.tex file

% Caption on top
% https://tex.stackexchange.com/a/14862/4762
\\usepackage{floatrow}
\\floatsetup[figure]{capposition=top}
\\floatsetup[table]{capposition=top}

PDF output


回答1:


You can use the output format bookdown::pdf_document2 instead of pdf_document, and the syntax for referencing a figure is \@ref(fig:chunk-label); see the documentation for details: https://bookdown.org/yihui/bookdown/figures.html




回答2:


Following I can't generate \label{fig:mwe-plot} with knitr, adding \label{...} to the caption arguments will produce labels in the underlying tex file, i.e.

```{r fig1, echo=FALSE, fig.cap="\\label{fig:fig1}This is a caption"}
plot(mtcars$wt, mtcars$mpg)
```

and

```{r tab2, echo=FALSE}
library(knitr)
kable(mtcars[1:3,1:4], caption="\\label{tab:tab2}A `kable` table")
```



回答3:


You can try the captioner package. You can find examples in this link.

In my case, I include a code chunk with:

table_captions <- captioner::captioner(prefix="Tab.")
figure_captions <- captioner::captioner(prefix="Fig.")

t.ref <- function(label){
  stringr::str_extract(table_captions(label), "[^:]*")
}

f.ref <- function(label){
  stringr::str_extract(figure_captions(label), "[^:]*")
}

I include captions in tables and figures when defining code chunks, like this:

```{r chunk_creating_one_figure, echo=FALSE, fig.cap=figure_captions("one_figure", "figure label")}
plot(1)
```

or

```{r chunk_creating_one_table, echo=FALSE, fig.cap=table_captions("one_table", "table label")}
knitr::kable(data.frame(col="something"), format="markdown")
```

References are included as inline_text all across my Rmarkdown with:

As shown in figure `r f.ref("one_figure")`
Data is shown on table `r t.ref("one_table")`


来源:https://stackoverflow.com/questions/38861041/knitr-rmarkdown-latex-how-to-cross-reference-figures-and-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!