Hi I am trying to use flextable
in an Rmarkdown .doc document to format my tables. I like the simple formatting options that flextable
gives (but open to other similar packages) but have found something that I thought should be a basic function doesn't always work.
I want to fit the table to the width of the word document so that if required text will wrap within a column to fit, but if there is free space available on the page columns will be made wider, but not to the extent that the column is so wide that not all data is shown.
I have made an example below to show my problem. By default all columns are the same width and text is wrapped to fit, but there is therefore space wasted. I want to fit columns to the data (using autofit
) but this then makes the columns so wide they go off the screen. I'm hoping for a happy-medium with mpg
, vs
and carb
wider but some text wrapping still happening. E.g. I want this:
Obviously I can manually change widths using flextable::width
but my table is made through an automated process so I don't know how wide I want each column to be.
Here is my example which shows the problems either with or eithout autofit
---
title: "TestTable"
output: word_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
suppressWarnings(suppressPackageStartupMessages({library(knitr)
library(pander)
library(flextable)
library(tidyverse)
library(flextable)}))
```
## Normal Table
Without extra formatting, wraps text so that it fits on the page, but there is no need for column widths to be equal and could be wider on the page
```{r, echo=FALSE, results = 'asis' }
mydata <- mtcars %>% head(3) %>% select(mpg, cyl, hp,vs, gear, carb) %>%
mutate(mpg = paste0(mpg, "with extra stuff to make long"),
vs = paste0(vs, "+ extra stuff"),
carb = paste0(carb, "also with extra stuff to make longer"))
mytable <- mydata %>% flextable(theme_fun = theme_box)
mytable
```
## Table With autofit
But table with autofit goes off the edges of the page
```{r, echo=FALSE, results = 'asis' }
mytable %>% autofit()
```
## Table With autofit and manual breaks
And if manual breaks are inserted into the column autofit makes the columns too wide an they still go off the edges of the page
```{r, echo=FALSE, results = 'asis' }
mydataWithBreaks <- mtcars %>% head() %>% select(mpg, cyl, hp,vs, gear, carb) %>%
mutate(mpg = paste0(mpg, "\nwith extra stuff\n to make long"),
vs = paste0(vs, "+\n extra stuff"),
carb = paste0(carb, "\nalso with extra stuff\n to make longer"))
mydataWithBreaks %>% flextable(theme_fun = theme_box)%>% autofit()
```
I have written a function to fit the table to the page which works well for now, although I'm still a bit surprised that there is no built in function to do this which would (for example) know the width of the page itself, so if any one knows any still keen to hear.
FitFlextableToPage <- function(ft, pgwidth = 6){
ft_out <- ft %>% autofit()
ft_out <- width(ft_out, width = dim(ft_out)$widths*pgwidth /(flextable_dim(ft_out)$widths))
return(ft_out)
}
FYI - I ran into this same problem today and used your code (thank you). But it still was bothering me because I couldn't get it quite right. I noticed on the Officedown package website (same author; https://github.com/davidgohel/officedown) they used set_table_properties(layout = "autofit")
so I tried that. For whatever reason it worked as expected when doing that! I also was using officedown
with default settings, so maybe the two worked well together.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With