I'm looking for a way to apply autofit() only to columns that are too small.
This is my current method but I'm looking for a better way to do it:
library(flextable)
library(magrittr)
### Ex. Tbls
vendor <- data.frame("Vendor" = rep("Acme", 4),
"Sales" = c(20,30,12,32))
vendor <- data.frame("Vendor" = rep("A long Company Name", 4),
"Sales" = c(21,23,43,12))
vendor <- data.frame("Vendor" = rep("A longer Company Name", 4),
"Sales" = c(1e20,2e20,3e20,4e20))
### Current Method:
desiredWidths <- c(.5,.5)
flextable(vendor) %>%
autofit() %>%
width(j = which(dim(.)$widths < desiredWidths), desiredWidths[which(dim(.)$widths < desiredWidths)])
Ideally I would like something like this:
flextable(vendor) %>%
width(width = desiredWidths) %>%
autofit(--Only expands columns that are too narrow--)
Is something like this possible?
If I understand you correctly, you want to set a minimal column width for each column and autosize the column in case any content inside exceeds this width, so that no text is wrapped.
For this, you can use strwidth
in this case for Arial point 11, and measure the maximum text widths of each column, if it's below your minWidths, set it to minWidths using pmax()
+ width
. This is a manual way of autosizing with a lower threshold. You need to adjust this, should you use another font / fontsize.
---
title: "flextabelWidth"
output:
pdf_document: default
html_document:
df_print: paged
---
```{r flexTables, echo=FALSE, warning=FALSE, ft.align="right"}
library(flextable)
### Ex. Tbls
vendor1 <- data.frame("Vendor" = rep("Acme", 4),"Sales" = c(20,30,12,32))
vendor2 <- data.frame("Vendor" = rep("A long Company Name", 4),"Sales" = c(21,23,43,12))
vendor3 <- data.frame("Vendor" = rep("A longer Company Name", 4),"Sales" = c(1e20,2e20,3e20,4e20))
autosize_min_width <- function(data, minWidths){
flextable(data) |> width(width = pmax(sapply(seq_along(names(
data
)), \(i) max(
strwidth(
format(data[, i], scientific = FALSE, trim = TRUE),
font = 11,
units = 'in'
)
)), minWidths))
}
desiredWidths <- c(.5,.5)
autosize_min_width(vendor1, desiredWidths)
autosize_min_width(vendor2, desiredWidths)
autosize_min_width(vendor3, desiredWidths)
```
giving you the minimal width you wanted
whereas your code
flextable(vendor) %>%
autofit() %>%
width(j = which(dim(.)$widths < desiredWidths), desiredWidths[which(dim(.)$widths < desiredWidths)])
which I guess is not what you want? In your code, you compare desiredWidths
with the widths already falsely set by autofit
to 0.75 inches, which seems to be the minimum width set by autofit
.