Prevent table being split in Rmarkdown - r

Is there a way to put my table into one page? I have a table which is broken between two pages. Here is a reproducible example:
---
output: pdf_document
---
`r rep("Text", 400)`
```{r}
# This will create a page break
knitr::kable(mtcars, caption = "A split table")
```
This produces a 2 page pdf with a broken table as follows::

There are two easy ways to do this:
1. Add a page break
If you are only using the PDF output, you can actually integrate LaTeX commands directly into the report. Therefore the \newpage command will force a pagebreak as follows:
---
output: pdf_document
---
`r rep("Text", 400)`
\newpage
```{r}
knitr::kable(mtcars, caption = "A fixed table")
```
2. Use Page Floats:
As RMarkdown uses LaTeX to build the PDF, you can take advantage of the page floats feature. This can take some getting used to, but rather than locking the figure or table in a set position, LaTeX will try and place the figure in a position which it deems "best". With tables, it will try and remove any page breaks.
Here is an example. The table will float to the second page. Make sure to update the YAML to include the header-includes: argument as well:
---
output: pdf_document
header-includes:
- \usepackage{booktabs}
---
`r rep("Text", 400)`
```{r}
knitr::kable(mtcars, format = "latex",
caption = "A caption",
booktabs = TRUE,
longtable = FALSE)
```
`r rep("Text", 200)`
If you look at the output, you will see that the second chunk of text continues on the same page as the first, and that the table is centered on the second page. This is all done automatically by LaTeX and can avoid pain down the road if you add more text before the table which might have previously caused the table to be broken again.
Hope that helps.

Related

cross reference to a table in rmarkdown with the correct table number in word document

I am trying to reference a table in a word document using bookdown package.
I wanted to add the reference id in the fig.cap parameter of the code chunk, but this is somehow not seen by the interpreter and I don't get the link to the reference.
As a workaround, I added my reference ID to the caption of the table, but here the full id ({#mysecondtable2}) is written in the figure caption and this looks ugly.
Any idea on how to solve this? Maybe LUA filter to remove the ugly anchor from the table caption? I don't understand how to do this.
---
title: "Untitled"
author: "Mario"
date: '2022-11-10'
output:
bookdown::word_document2:
toc: true
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
See Table \#ref(tab:myfirsttable). Or click [Table \#ref(tab:mysecondtable)](#mysecondtable2).
```{r myfirsttable, echo = FALSE}
knitr::kable(cars, caption = "First three rows of cars dataset")
```
See Table \#ref(tab:mysecondtable).
```{r mysecondtable, echo = FALSE, fig.cap='{#mysecondtable2}'}
knitr::kable(head(iris, 3),
caption='{#mysecondtable2} test')
```
EDIT:
Some strange behaviour shows, that [Table \#ref(tab:mysecondtable)](#mysecondtable) seems to work. But actually it only refers to the caption of the second table but ignores the 2 at the end...
One straight-forward solution is to wrap the table into an extra div, as one can then link to that div:
Or click [Table \#ref(tab:mysecondtable)](#mysecondtable-wrapper).
::: {#mysecondtable-wrapper}
```{r mysecondtable, echo = FALSE}
knitr::kable(head(iris, 3),
caption='test')
```
:::
A slightly less crude way is to put a span into the caption:
knitr::kable(head(iris, 3),
caption='[test]{#mysecondtable}')
The difference between the two is that the link will point at the whole table when using a div, and to the caption when using a span.

How to create a footer on powerpoint slide using R packages officedown and officer

Revised a second time!!
There is an example .rmd that comes with the officedown package and in that are chunks that show how you can use the officer package placeholder ("ph") tags within the chunk options, which is great. Here is a minimum reproducible example:
---
title: YAML Title
output:
officedown::rpptx_document
---
```{r echo=FALSE}
library(officedown)
```
## Slide 1 Title
```{r echo=FALSE, layout="Title and Content", ph=officer::ph_location_type(type="ftr")}
test <- data.frame(1)
test
```
The problem now is that if I try to insert a string instead of a data frame in the footer ("ftr"), then that string is instead placed in the body of the pptx slide, please see the example below.
---
title: YAML Title
output:
officedown::rpptx_document
---
```{r echo=FALSE}
library(officedown)
```
## Slide 1 Title
```{r echo=FALSE, layout="Title and Content", ph=officer::ph_location_type(type="ftr")}
"Some footer text"
```
And so now I'm very close but need help to get a string to appear in the footer. I tried a hack of making a single cell data frame with the string I want in that cell but that did not work either.
Thank you for reading!
Revised thanks to commenters!
I am trying to use officedown combined with the officer package to write out a footer to a slide. I thought to create a code chunk in the .Rmd with code that I know works in a .R script using officer.
Using the example code below, it successfully creates 2 slides. However, on the second slide I would like to have a footer with the text "a footer". Instead on the second slide only the title appears. Is there a way to insert a footer using officedown?
The reasons I thought it might be possible was after reading this on the officedown page: "The package also enhances PowerPoint productions with R Markdown by providing a mechanism for placing results according to the slide template contained in the PowerPoint document used as "reference_doc" " - https://davidgohel.github.io/officedown/
Thank you for taking a look and here is the revised example code.
---
title: YAML Title
output:
officedown::rpptx_document
---
```{r setup, include=FALSE}
library(officedown)
library(officer)
```
## Slide 1 Title
```{r echo=FALSE}
my_pres <- read_pptx()
my_pres <- add_slide(my_pres, layout = "Title and Content", master = "Office Theme")
my_pres <- ph_with(my_pres, value = "a footer", location = ph_location_type(type = "ftr"))
```

How to combine endfloat, markdown formatting and wordwrap in bookdown::pdf_document2 table

I am writing a Rmarkdown document using bookdown::pdf_document2 for which I have a table that needs to do several very specific things, but I simply cannot find the solution to get all of them to work at the same time:
The table needs to float to the end of the document as it would with the latex endfloat package.
The table elements have Markdown bold and italics formatting that should appear correctly in the final PDF document
One of the columns of the table has a lot of text that I would like to wrap within the table cell.
I have tried to get these three options to work with all sorts of combinations of knitr::kable, kableExtra::column_spec and pander, but I cannot find a way to get them all going at once. Below I am pasting an example Rmarkdown document with various tests, none of which fully works.
Is there a simple way to get the table to do what I want? Even a good workaround would be acceptable...
Thanks,
David
---
title: "Test table formatting"
author: "David M. Kaplan"
date: "5/24/2020"
output: bookdown::pdf_document2
header-includes:
- \usepackage[tablesfirst]{endfloat}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
```
# Data
```{r}
df.long = data.frame(
char = c('*this is some very long text with lots of words that will cause problems with word wrap if it is not properly handled with something like kableExtra*','**b**','~~c~~'),
num = c(1,2,3))
```
# Kable with format=pandoc
```{r}
knitr::kable(df.long,caption="test1",format="pandoc")
```
**Result:** Handles formatting, but table does not float and no wordwrap.
# Kable with booktab
```{r}
knitr::kable(df.long,caption="test2",booktab=TRUE)
```
**Result:** Floats, but does not handle formatting or do wordwrap.
# kableExtra for wordwrap
```{r}
knitr::kable(df.long,caption="test3",booktab=TRUE) %>%
kableExtra::column_spec(1,width="30em")
```
**Result:** Table floats and has wordwrap, but does not handle formatting.
# Pander
```{r}
pander::panderOptions("table.alignment.default","left")
pander::pander(df.long,caption="test4")
```
**Result:** Wordwrap and formatting, but does not float.
I found a solution to this problem. It basically consists of:
In the YAML header, add a header-includes entry declaring longtable to be a float flavor using some LaTeX magic I found here.
Use pander to format the table to get wordwrap
Specifically, I have the following in the YAML header:
header-includes:
- \usepackage[tablesfirst]{endfloat}
- \DeclareDelayedFloatFlavour*{longtable}{table}
and then the table can be generated with pander:
pander::panderOptions("table.alignment.default","left")
pander::pander(df.long,caption="test pander",split.cell=50)

How can I change the number of columns several times in an R Markdown pdf document?

I am creating a .pdf using R Markdown. I would like to have a section of text in two column format, and then follow that with a graph (or table, photo, etc.) that takes up the entire width of the page, and then return to two column text. I am new at Markdown / LaTex / Pandoc and I cannot figure out how to do it.
This answer by #AlisonShelton appears to be what I want, but when I run it I get this error in the RStudo R Markdown console:
! Undefined control sequence.
l.87 \btwocol
pandoc.exe: Error producing PDF
Error: pandoc document conversion failed with error 43
I have successfully used this method by #scoa to make a two column .pdf, but I don't know how go back and forth between one and two columns using this.
Here is some sample code for testing purposes
---
title: "Test"
output: pdf_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Two columns of text
This seciton should be in two column format.
Here are a bunch of ? to make it longer: ???????????????????????????????????????????????????????????????????????????????
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??????????????????????????????????????????????????????????????????????????????????????????????????????????????????
## Once column section.
This part should be the whole page width
```{r plot}
plot(rnorm(20),rnorm(20))
```
## Now 2 columns again
This section should go back to two columns !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
What you can do is first, to add -- as you stated -- pandoc_args: ... into your YAML header. Second, there are a few LaTeX solutions around (like this or this one) which won't work for RMarkdown. The only way I found so far is to use \onyecolumn / \twocolumn -- just with the drawback of the page breaks. But perhaps you can live with it until there's a better solution.
---
title: "Test"
output:
pdf_document:
pandoc_args: [
"-V", "classoption=twocolumn"
]
html_document: default
header-includes:
- \usepackage{lipsum} # just used for producing example text in document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Two columns of text
\lipsum[1-7]
\onecolumn
## Once column section.
This part should be the whole page width
```{r plot}
plot(rnorm(20),rnorm(20))
```
\lipsum[1]
\twocolumn
## Now 2 columns again
This section should go back to two columns
\lipsum
\begin{table*}
This is nice, but won't work with R chunks or headers. And you'll have to format with LaTeX code (e.g. \textbf{Foo blaah}).
\lipsum[1]
\end{table*}
\lipsum

How to put a crossreference in Rbookdown?

I am not sure I understand this part from the documentation
the table label for a code chunk with the label foo will be tab:foo
Say I have a RMarkdown chunck such as
```{r mytable, echo=FALSE}
kable(df, booktabs=T)
```
I would consider mytabel as the label for the code chunck. That means I should be able to type a narrative that looks like:
This is my table \#ref(tab:mytable)
And the \#ref should reference the table number instead of the chucnk id. Instead I get a double (and clickable) ?? .What am I doing wrong?
In the second paragraph of the documention:
Like figures, tables with captions will also be numbered and can be referenced.
So you want to cross-reference a table, you must specify the caption argument.
You can create a empty RStudio project and or save following code as index.Rmd file. Or download
https://github.com/yihui/bookdown-minimal and replace the content of index.Rmd file with the following code. Then you can press Build Book button in the Build panel.
---
title: "A Book"
author: "Frida Gomam"
site: bookdown::bookdown_site
output:
bookdown::gitbook: default
---
# reference
This is my table \#ref(tab:mytable)
# table
```{r mytable, echo=TRUE}
knitr::kable(iris[1:10, ], booktabs=T, caption='A table of the first 10 rows of the mtcars data')
```

Resources