49

I would like wrap long text in my kable table. Here is a simple example of a table with column text that is too long and needs to be wrapped for the table to fit on the page.

---
title: "test"
output: pdf_document
---

```{r setup, include=FALSE}
  library(knitr)
```


This is my test

```{r test, echo=FALSE}
test <- data.frame(v1=c("This is a long string. This is a long string. This is a long string. This is a long string. This is a long string.",
                        "This is a another long string. This is a another long string. This is a another long string. This is a another long string. This is a another long string."),
                   v2=c(1, 2))
kable(test)
```

enter image description here

Eric Green
  • 7,385
  • 11
  • 56
  • 102

2 Answers2

63

An alternative solution other than the awesome pander package is to use column_spec in kableExtra. In this case, the following code will do the trick.

kable(test, "latex") %>%
  column_spec(1, width = "10em")
Hao
  • 7,476
  • 1
  • 38
  • 59
  • 3
    If your table is floating outside the page, `kable_styling(full_width = TRUE)` from the kableExtra package will also introduce wrapping of text if needed. – fry Jun 22 '21 at 13:02
  • I think this should be clear `kable_styling(full_width = FALSE)` when format in kable(format="latex"). So in this case wrapping text will not work. – Lunalo John Jun 10 '22 at 22:15
29

I've created the pander package to produce markdown tables in a flexible way. By default, it will split cells with long string to 30 chars, but there are a bunch of global options and fn arguments to override that, enable hyphenation and other tweaks. Quick demo:

> pander::pander(test)

-----------------------------------
              v1                v2 
------------------------------ ----
This is a long string. This is  1  
a long string. This is a long      
string. This is a long string.     
    This is a long string.         

This is a another long string.  2  
This is a another long string.     
This is a another long string.     
This is a another long string.     
This is a another long string.     
-----------------------------------

> pander::pander(test, split.cell = 80, split.table = Inf)

------------------------------------------------------------------------------------
                                      v1                                         v2 
------------------------------------------------------------------------------- ----
This is a long string. This is a long string. This is a long string. This is a   1  
                      long string. This is a long string.                           

This is a another long string. This is a another long string. This is a another  2  
  long string. This is a another long string. This is a another long string.        
------------------------------------------------------------------------------------
daroczig
  • 28,004
  • 7
  • 90
  • 124
  • 1
    looks very slick, @daroczig. is there an argument for column names? sorry if I missed it. – Eric Green Apr 03 '15 at 04:11
  • 1
    Thank you @EricGreen. What argument do you miss for colnames? Probably you'd better set those at the `data.frame` level. – daroczig Apr 03 '15 at 04:15
  • `kable` has `col.names` to redefine "v1" to "My text" – Eric Green Apr 03 '15 at 04:16
  • for my current use case, setting at the data.frame level worked fine. i'm not sure i would always want to do this, but nice in this case. great work on `pander` – Eric Green Apr 03 '15 at 04:25
  • Thanks for the feedback @EricGreen. To be honest, I've never had any real need for such new argument in `pander` and I always tweak the actual `data.frame` to fit my needs before passing to `pander`, but if you can describe a good use-case, then please open an issue on GH. – daroczig Apr 03 '15 at 05:13
  • Use case: tables without meaningful column names. For instance, I have a table where columns are defined by combinations of logical conditions (e.g. column 1 is the value when conditions 1, 2, and 3 are all true, column 2 has condition 3 false, etc.), and I want to represent this information compactly by making each condition a row with TRUE/FALSE and the values below rather than putting all that in each column heading. This is common in regression tables, for instance, but those usually also have meaningful column headers. – randy Jul 06 '19 at 22:01