KableExtra adding linebreaks in columns with long nonwhitespace strings - r

I have a long string which I want in a table, for instance 100x the letter A (AAA...). I would like kable to split this string into multiple lines if they don't fit in the table instead of making these strings overflow such as shown
here.
I noticed kable is actually able of doing so, provided there are newlines or -'s in your string, see for instance here.
However, I would like kable to do this splitting on either selected characters or on any character, so the output result would be this, but I don't know how to achieve this. I had a look on SO and in the kableextra documentation, but no luck. Any suggestions?
Below is a chunk to play around with.
---
title: 'rasstasrt'
sansfont: Calibri Light
output: pdf_document
---
```{r setup, include=FALSE}
library(kableExtra);
library(dplyr)
knitr::opts_chunk$set(cache = F)
```
```{r}
dt <-tibble(Items =c("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaAAa", "Item 2", "Item 3"),
Tmd5ext_1 =c("Lorem ipsum "),
Text_2 =c("Duis pos "))
kableExtra::kable(dt, "latex", booktabs = F, col.names =c("Item", "Short Title", "Veryong Title")) %>% column_spec(1:3, width = "5cm", )
```

You can leverage the newline character in latex, \\ and the argument escape = FALSE in kableExtra::kable(). Settting escape = FALSE causes the \\ to be read as newline characters instead of literal \\. Note that because \ is an escape character in R, you need two slashes \\ in order for R to interpret a single slash \, so to get 2 literal slashes \\ you need to put 4 \\\\ in the string.
---
title: 'rasstasrt'
sansfont: Calibri Light
output: pdf_document
---
```{r setup, include=FALSE}
library(kableExtra)
library(dplyr)
knitr::opts_chunk$set(cache = F)
```
```{r}
dt <-tibble(Items = c("AAAAAAAAAAAAAAA\\\\AAAAAAAAAA\\\\AAAAAAAAAAA\\\\AAAAAAAAAAAAA\\\\AAAAAAaaaaAAa",
"Item 2",
"Item 3"),
Tmd5ext_1 = c("Lorem ipsum "),
Text_2 = c("Duis pos "))
kableExtra::kable(dt,
"latex",
booktabs = F,
col.names =c("Item", "Short Title", "Veryong Title"),
escape = FALSE) %>%
column_spec(1:3, width = "5cm")
```
Alternatively, if you wanted to insert the newline after a specific number of characters, you could write a function to do that.
---
title: 'rasstasrt'
sansfont: Calibri Light
output: pdf_document
---
```{r setup, include=FALSE}
library(kableExtra)
library(dplyr)
knitr::opts_chunk$set(cache = F)
```
```{r}
add_return <- function(x, len) {
# intialize empty vector
y <- c()
# start at beginning of string
i <- 1
# Break string up into lengths of len
while(i < nchar(x)) {
y <- c(y,substr(x, i, i + len - 1))
i <- i + len
}
# concatenate the substrings together with the newline characters
paste0(y, collapse = "\\\\")
}
dt <-
tibble(
Items = c(
add_return(
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaAAa",
len = 5
),
"Item 2",
"Item 3"
),
Tmd5ext_1 = c("Lorem ipsum "),
Text_2 = c("Duis pos ")
)
kableExtra::kable(
dt,
"latex",
booktabs = F,
col.names = c("Item", "Short Title", "Veryong Title"),
escape = FALSE
) %>% column_spec(1:3, width = "5cm")
```
You could also use regular expressions to insert the return after a specific character string.
---
title: 'rasstasrt'
sansfont: Calibri Light
output: pdf_document
---
```{r setup, include=FALSE}
library(kableExtra)
library(dplyr)
knitr::opts_chunk$set(cache = F)
```
```{r}
regex_add_return <- function(x, after) {
gsub(pattern = paste0("(",after,")"), replacement = paste0("\\1\\\\\\\\"),x)
}
dt <-
tibble(
Items = c(
regex_add_return(
"AAAAAAAAAAAAAAAz123AAAAAAAAAAAAAAAz123AAAAAAAAAAz123AAAAAAAAAAAAAAAaaaaAAa",
after = "z123"
),
"Item 2",
"Item 3"
),
Tmd5ext_1 = c("Lorem ipsum "),
Text_2 = c("Duis pos ")
)
kableExtra::kable(
dt,
"latex",
booktabs = F,
col.names = c("Item", "Short Title", "Veryong Title"),
escape = FALSE
) %>% column_spec(1:3, width = "5cm")
```
Note that there are 8 slashes in gsub() because the slash is also an escape character for regular expressions, so each literal slash has to be escaped with a slash, but then each slash that is being used as an escape character for regex also has to be escaped again for R, requiring another slash.

Related

RMarkdown Change numbering for tables in PDF document

I want to change the numbering of the tables in the RMarkdown document so that all tables in the appendix have an "A-" in front of the number, thus: "Table A-2".
Only in the appendix. Otherwise with normal numbering ("Table 1").
However, I am not really getting anywhere.
Here is my reproducible example:\
---
title: "This is my title"
date: "`r Sys.setlocale(locale = 'English') ; format(Sys.time(), '%B %d, %Y')`"
output: pdf_document
---
```{r echo = F, message = F, warning = F}
library(tidyverse)
library(knitr)
``` #The hash mark must be removed!
# Results
```{r echo = F, message = F, warning = F}
tribble(~column1, ~column2,
"value1", 2,
"value2", 5
)%>%
kable(booktabs=T, caption = "This is the caption of the first table")
```
# Appendix
```{r echo = F, message = F, warning = F}
tribble(~column1, ~column2,
"value1", 6,
"value2", 8
)%>%
kable(booktabs=T, caption = "This is the caption of the second table")
```
This is really a LaTeX question, and I found the answer here.
You add these LaTeX lines after your Appendix title:
\setcounter{table}{0}
\renewcommand{\thetable}{A\arabic{table}}

Table rendering in pdf document using R markdown

After days trying to find a solution, I give up and ask for help.
I decided to use R Markdown very recently. While I can render plots as I want, I cannot succeed in rendering my tables in a pdf doc properly.
Here the corresponding [EDITED]code:
---
title: "My_title"
output:
pdf_document: default
html_document:
df_print: paged
params:
date: "!r Sys.Date()"
---
```{r library, echo=F, message=F, warning=F, paged.print=FALSE}
suppressMessages(library("knitr"))
suppressMessages(library(reshape2))
suppressMessages(library(splines))
suppressMessages(library(kableExtra))
suppressMessages(library(gplots))
```
```{r, setup, echo = F}
opts_knit$set(root.dir = "my_path")
knitr::opts_chunk$set(echo = F)
```
```{r}
dt <- expand.grid(Region=c("a","b","c"), Country=c("d","e","f"), Cancer= c("All", "CRC", "Breast"),
age.1.1=1:2,
age.1.2=1:2,
age.1.3=1:2)
```
```{r Table_1, INCLUDE = TRUE}
cancer.lab <- c("All", "CRC", "Breast")
for (i in 1:3){
b <- dt[dt$Cancer==cancer.lab[i],]
b <- b[,-3]
t <- kable(b, format = ,caption = "Fig", row.names = F) %>%
kable_paper() %>%
kable_styling(font_size = 9) %>%
add_header_above(c(" " = 2, "1998" = 3))
print(t)
}
```
Again I am new and I surely miss something.
I use Mac if it may explain something.
Thank you for your help.
Sophie.
I think this is the same issue as dealt with here: https://stackoverflow.com/a/53632154/2554330. The problem is that you need to use knit_print to print the tables, but you can't do that in a loop.
So if you change the last code chunk to this, it should work:
```{r Table_1, INCLUDE = TRUE}
results <- c()
cancer.lab <- c("All", "CRC", "Breast")
for (i in 1:3){
b <- dt[dt$Cancer==cancer.lab[i],]
b <- b[,-3]
t <- kable(b, format = ,caption = "Fig", row.names = F) %>%
kable_paper() %>%
kable_styling(font_size = 9) %>%
add_header_above(c(" " = 2, "1998" = 3))
results <- c(results, knit_print(t))
}
asis_output(results)
```

Render superscript in pander table in RMarkdown

I'm trying to render a pander table in RMarkdown that includes superscript. Here is my current RMarkdown code:
```
---
title: "My Table"
output: html_document
---
```{r packages, include = FALSE}
library(tidyverse)
library(pander)
```
```{r my_table}
my_table <-
data.frame(
c("Sector 1",
"Sector 2",
"Sector 3"),
c("100%",
"29%",
"NA"))
pander(my_table,
col.names = c("Sector", "% Coverage"),
split.cells = 40,
keep.line.breaks = TRUE)
```
And here is the knit result:
I would like to add a superscripted letter "c" to the "NA" cell of the table, yielding an output like this:
You are looking to use the notation $$ NA^c $$, but this only works outside of the R chunk at the moment.

KableExtra math symbols

How can I insert 'equal or greater than' symbol in a kable?
On the small rmarkdown doc below I tried two different ways based on some
internet suggestions but neither work. I did try the argument 'escape=FALSE' but
it does not work either. Thanks for any pointers...
title: "Math symbols in column headers"
date: "January 15, 2020"
output: pdf_document
---
```{r}
library(kableExtra)
library(knitr)
a <- structure(list(MLE = c(0.0839, 0.2082, 0.4194, 0.8237, 1.6201
), MME = c(0.0839, 0.2082, 0.4194, 0.8234, 1.6147)), class = "data.frame", row.names = c(NA,
5L))
colnames(a) <- c("abundance of\n White Sharks\n $\\\\geq$ 40 inches","Percentage of \n White shark in
the population\n $\\\\geq{40}$ inches")
```
```{r}
kable(a, "latex", booktabs = T)
```
This is what I get...
You need to end up with \geq in the Markdown file. To get that, you enter "\\geq" in the R string, and specify escape = FALSE in the call to kable(). That is,
---
title: "Math symbols in column headers"
date: "January 15, 2020"
output: pdf_document
---
```{r}
library(kableExtra)
library(knitr)
a <- structure(list(MLE = c(0.0839, 0.2082, 0.4194, 0.8237, 1.6201
), MME = c(0.0839, 0.2082, 0.4194, 0.8234, 1.6147)), class = "data.frame", row.names = c(NA,
5L))
colnames(a) <- c("Abundance of\n White Sharks\n $\\geq 40$ inches","Percentage of \n White shark in
the population\n $\\geq 40$ inches")
```
```{r}
kable(a, "latex", booktabs = T, escape = FALSE)
```
This gives me
To respect the linebreaks, you need to use the linebreak function from kableExtra, i.e. something like this:
colnames(a) <- linebreak(c("Abundance of\n White Sharks\n $\\geq 40$ inches",
"Percentage of \n White shark in the population\n $\\geq 40$ inches"))
kable(a, "latex", booktabs = TRUE, escape = FALSE, align = "c")
which gives this output:

R kableExtra latex: Add linebreaks to rotated header row

I'm trying to produce table to a Latex-pdf document. I'm using kableExtra and knitr in R.
I have a table that has long column names. When I rotate the header row by 90 degrees linebreaks won't work. Does anyone have an idea how I could achieve both rotated row and linebreaks?
My example is the same as in Hao's Best Practice for newline in Latex table, but I added piped row_spec to the end of the code.
\documentclass[10pt,a4paper]{article}
\usepackage[table]{xcolor}
\begin{document}
\begin{table}
<<global_options, echo=FALSE>>=
library(kableExtra)
library("dplyr")
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
dt_lb %>%
mutate_all(linebreak) %>%
kable("latex", booktabs = T, escape = F,
col.names = linebreak(c("Item\n(Name)", "Value\n(Number)"))) %>%
row_spec(0, angle = 90, align='l', monospace=T)
#
\end{table}
\end{document}
What I get is this, but the [l] tags hint that there's something else wrong with the tags as well:
On StackExchange TEX I found a question about rotation and linebreaks, this is what I'm trying achieve: https://tex.stackexchange.com/questions/14730/big-table-with-rotated-column-labels-using-booktabs
You could use tableHTML:
library(tableHTML)
Replace the new line character "\n" with the HTML tag <br>:
headers <- c("Item\n(Name)", "Value\n(Number)") %>%
stringr::str_replace_all(pattern = "\\n", replacement = "<br>")
Create a tableHTML object and rotate the headers using add_css_header():
dt_lb %>%
tableHTML(rownames = FALSE,
headers = headers,
escape = FALSE,
widths = c(100, 100),
theme = 'scientific') %>%
add_css_header(css = list(c('transform', 'height', 'text-align'),
c('rotate(-45deg)', '70px', 'center')),
headers = 1:2)
The result looks like this:
Note: you can add more css or default themes. Check out the vignettes for more details:
If you want to create a pdf document, you could use RMarkdown:
---
title: "tableHTML2pdf"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
\
```{r}
library(tableHTML)
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
headers <- c("Item\n(Name)", "Value\n(Number)") %>%
stringr::str_replace_all(pattern = "\\n", replacement = "<br>")
dt_lb %>%
tableHTML(rownames = FALSE,
headers = headers,
escape = FALSE,
widths = c(100, 100),
theme = 'scientific') %>%
add_css_header(css = list(c('transform', 'height', 'text-align'),
c('rotate(-45deg)', '70px', 'center')),
headers = 1:2)
```
\
It will then create an HTML file. This file can then be converted to PDF using wkhtmltopdf.
I think you probably rendered your rmarkdown document into HTML... In the rmarkdown yaml header, does it say html_document right now? If so, you can try to change it to pdf_document.....
I rendered a pdf_document with exactly the same code and I think I got what you were looking for...
---
title: "Table Sample"
output: pdf_document
---
``` {r, include = FALSE}
library(tidyverse)
library(kableExtra)
```
```{r}
dt_lb <- data.frame(
Item = c("Hello\nWorld", "This\nis a cat"),
Value = c(10, 100)
)
dt_lb %>%
mutate_all(linebreak) %>%
kable("latex", booktabs = T, escape = F,
col.names = linebreak(c("Item\n(Name)", "Value\n(Number)"), align = "c")) %>%
row_spec(0, angle = 90)
```
Latex package makecell was missing.
Hao pointed out that Page 3 of this manual lists some of the necessary Latex packages: haozhu233.github.io/kableExtra/awesome_table_in_pdf.pdf

Resources