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.