knitr / rmarkdown / Latex: как делать перекрестные ссылки на рисунки и таблицы?

Я пытаюсь сделать перекрестные ссылки на рисунки и таблицы в PDF-файле, созданном с помощью knitr / rmarkdown. Есть несколько вопросов по SO и tex.stackexchange (здесь и здесь, например), которые предлагают способ сделать это встроенным - добавить \ref{fig:my_fig}, где my_fig - метка фрагмента. Однако, когда я пробую это в своем rmarkdown документе, я получаю ??, где должен быть номер рисунка. Я хотел бы узнать, как заставить работать перекрестные ссылки.

Воспроизводимый пример ниже. Есть два файла: файл rmarkdown плюс файл header.tex, который я включил на тот случай, если он повлияет на ответ (хотя у меня такая же проблема, независимо от того, включаю ли я файл header.tex или нет).

В файле rmarkdown есть три примера перекрестных ссылок. Пример 1 - это рисунок, для которого не удается выполнить перекрестную ссылку (вместо номера рисунка отображается ??). Также есть вторая закомментированная попытка (на основе этого SO-ответа), где я пытаюсь установить среду рисунка , метка и заголовок с latex разметкой до и после фрагмента, но это приводит к pandoc ошибке, когда я пытаюсь связать документ. Ошибка:

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

В примере 2 используется xtable и перекрестные ссылки работают. В примере 3 используется kable, и перекрестная ссылка не выполняется.

Снимок экрана с выходным PDF-файлом включен в конце этого сообщения.

rmarkdown файл

---
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 файл

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

Вывод PDF

введите описание изображения здесь


person eipi10    schedule 09.08.2016    source источник
comment
Эта проблема, по-видимому, обсуждалась здесь: Я не могу создать \ label {fig: mwe-plot} с помощью knitr. Жесткое кодирование {r fig1, echo=FALSE, fig.cap="\\label{fig:fig1}This is a caption"}, похоже, работает.   -  person Weihuang Wong    schedule 10.08.2016


Ответы (3)


Вы можете использовать выходной формат bookdown::pdf_document2 вместо pdf_document, а синтаксис для ссылки на рисунок - \@ref(fig:chunk-label); подробности см. в документации: https://bookdown.org/yihui/bookdown/figures.html

person Yihui Xie    schedule 10.08.2016
comment
есть ли способ сделать это, совместимый с пользовательскими форматами rmarkdown, например из rticles шаблонов? - person cboettig; 20.10.2016
comment
@cboettig Да. Возможно, я недостаточно ясно дал понять: bookdown.org/yihui/bookdown/latexpdf.html Вы можете изменить base_format на любую функцию формата вывода в любых пакетах. - person Yihui Xie; 21.10.2016
comment
ответ Yihui выше, похоже, не работает для bookdown :: tufte_book2. Для рисунка перекрестная ссылка, которая отображается правильно с pdf_document2, отображается как ?? когда выходной формат изменен на tufte_book2. - person Moonhawk; 21.12.2016
comment
К вашему сведению, кажется, что нельзя изменить base_format для bookdown :: pdf_document2, но вместо этого следует использовать bookdown :: pdf_book… stackoverflow.com/a/52480807 / 576684 - person julou; 25.09.2018
comment
Я не уверен, как использовать формат pdf_document2 в rmarkdown файле? Я знаю только, как использовать с render_book. После добавления bookdown::pdf_document2 в раздел YAML в RStudio появляется опция knit to pdf_document2, но в остальном я не знаю, как это сделать из командной строки. - person James Hirschorn; 06.03.2020
comment
@JamesHirschorn render_book - это bookdown функция, с rmarkdown вы можете использовать render и передать bookdown::pdf_document2 как output_format, например : rmarkdown::render("Index.Rmd", output_format = bookdown::pdf_document2"). - person Trusky; 19.07.2021

Следуя , я не могу создать \ label {fig: mwe-plot} с помощью knitr, добавление \label{...} к аргументам заголовка приведет к созданию меток в базовом tex файле, т. е.

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

а также

```{r tab2, echo=FALSE}
library(knitr)
kable(mtcars[1:3,1:4], caption="\\label{tab:tab2}A `kable` table")
```
person Weihuang Wong    schedule 09.08.2016
comment
@Yihui, поскольку это основано на ответе двухлетней давности, это все еще современное состояние или есть ли лучшие способы сделать это сейчас? - person eipi10; 10.08.2016
comment
Теперь есть способы получше. Короче говоря, используйте bookdown::pdf_document2 вместо pdf_document; см. bookdown.org/yihui/bookdown/figures.html - person Yihui Xie; 10.08.2016

Вы можете попробовать пакет captioner. Примеры можно найти в этой ссылке.

В моем случае я включаю фрагмент кода с:

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), "[^:]*")
}

Я включаю подписи в таблицы и рисунки при определении фрагментов кода, например:

```{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")
```

Ссылки включены как inline_text во все мои Rmarkdown:

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