Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to cross reference tables and plots in rmarkdown?

I am using the following template

---
title: "Nice try buddy"
author: "SpaceMan"
date: "13 December 2057"
output:
  bookdown::pdf_document2
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage[table]{xcolor}
- \usepackage{wrapfig}
- \usepackage{float}
- \usepackage{colortbl}
- \usepackage{pdflscape}
- \usepackage{tabu}
- \usepackage{threeparttable}
- \usepackage{threeparttablex}
- \usepackage[normalem]{ulem}
- \usepackage{makecell}  
---
---
references:
- id: fenner2012a
  title: One-click science marketing
  container-title: Nature Materials
  volume: 11
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Title

\begin{equation}
f\left(k\right)=\binom{n}{k}p^k\left(1-p\right)^{n-k} \label{eq:binom}
\end{equation}

You may refer to it using `\@ref(eq:binom)`, e.g., see Equation \@ref(eq:binom).
and not a nice citation! @fenner2012a


## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mytable
```

## References

where mytable is stored in R session and is generated with

mytable <- head(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
kable_styling(latex_options = 'HOLD_position')

Now, this is supposed to work, but when I knit the document using

rmarkdown::render('C:\\Users\\john\\Documents\\bbv.Rmd')

  • the cross-reference for the table is not there! I only see ??
  • and the table has this weird #tab thing - how to get rid of it ?
  • the TOC is here even though I did not ask for it

enter image description here

Any ideas how to fix these issues? Thanks!

EDIT: the weird #tab thing disappeared after a reboot.

like image 923
ℕʘʘḆḽḘ Avatar asked Sep 23 '18 03:09

ℕʘʘḆḽḘ


Video Answer


1 Answers

The problem is that you are working against the intentions of kable by using it outside of an R chunk:

The kable() function will automatically generate a label for a table environment, which is the prefix tab: plus the chunk label.

https://bookdown.org/yihui/bookdown/tables.html

So the following workaround is definitely on the hacky side. Using a file foo.Rmd with

---
output:
  bookdown::pdf_document2:
    toc: no
header-includes:
- \usepackage{float}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```


## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mytable
```

You can also embed tables, for example:  \@ref(tab:tw2)

```{r tw2, echo=FALSE}
mytable2
```

Referencing images is easier: \@ref(fig:plt)

```{r plt, echo=FALSE, fig.cap = 'hello', fig.height=3} 
myplot 
``` 

one can process this file with a second file foo.R:

library(knitr)
library(kableExtra)
# add the label to the options that would normally be populated from the chunk options
opts_current$append(list(label = "tw"))
mytable <- head(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
opts_current$restore()

opts_current$append(list(label = "tw2"))
mytable2 <- tail(cars) %>% kable(format = "latex", 
                                booktabs = T, 
                                caption = "Demo Table", 
                                escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
opts_current$restore()

myplot <- ggplot(cars, aes(x = dist, y = speed)) + geom_point()

rmarkdown::render("foo.Rmd")

In principle, you can do these commands also just at the R prompt, but I try to not use the prompt directly. BTW, I do not get the (#tab) output with your code.

However, I think it makes more sense to not work against the workings of kable. I can understand that it can make sense to separate the data manipulation fro the presentation. However, creating the table is presentation from my point of view. So instead of creating the table externally I would just create the data externally. To make this concrete, let's use a file bar.Rmd:

---
output:
  bookdown::pdf_document2:
    toc: no
header-includes:
- \usepackage{float}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(kableExtra)
```

## Including Tables

You can also embed tables, for example:  \@ref(tab:tw)

```{r tw, echo=FALSE}
mydata %>% kable(format = "latex", 
                 booktabs = T, 
                 caption = "Demo Table", 
                 escape = F) %>%
  kable_styling(latex_options = 'HOLD_position')
```

together with a file bar.R:

# insert data processing here
mydata <- head(cars)
rmarkdown::render("bar.Rmd")

This gives me the same output and the data processing is (initially!) separated from the presentation.

like image 185
Ralf Stubner Avatar answered Oct 20 '22 14:10

Ralf Stubner