Search code examples
rflextablegtsummary

flextable and gtsummary: Title font is different from body font with save_as_docx()


I am trying to print regression tables to Microsoft Word files with gtsummary and flextable. However, despite specifying the styling whenever possible, the title of the table prints in a different font than the rest of the table. I want everything to be in Times New Roman/APA Style, but the title font keeps printing in Cambria. Outside of R, my default Microsoft Word font is Calibri.

I know there are other packages that can print regression tables to Microsoft Word, but I prefer gtsummary and flextable because my actual data is multiply imputed and I have found that gtsummary and flextable work well with multiply imputed data. This is a small issue, but any help is appreciated.

library(tidyverse)
library(gtsummary)
library(flextable)

packageVersion("gtsummary")
#> [1] '1.5.1'
packageVersion("flextable")
#> [1] '0.6.11.4'

# theme based on https://github.com/idea-labs/comsldpsy
apa_theme <- function (ft)  {
  ft %>%
    flextable::font(fontname = "Times New Roman", part = "all") %>% 
    flextable::fontsize(size = 12, part = "all") %>% 
    flextable::align(align = "left", part = "all") %>% 
    flextable::align(align = "center", part = "header") %>% 
    flextable::rotate(rotation = "lrtb", align = "top", part = "body") %>% 
    flextable::border_remove() %>% 
    flextable::hline_top(border = officer::fp_border(width = 2), part = "all") %>% 
    flextable::hline_bottom(border = officer::fp_border(width = 2), part = "all") %>% 
    flextable::autofit()
}

set_flextable_defaults(font.family = "Times New Roman")

m1 <- lm(response ~ trt, data = trial) %>% tbl_regression()
m2 <- lm(response ~ trt + marker, data = trial) %>% tbl_regression()
m3 <- lm(response ~ trt + marker + age, data = trial) %>% tbl_regression()

tbl_merge(
  tbls = list(m1, m2, m3)) %>%
  modify_table_styling(align = "left") %>%
  modify_caption("Why is the title in a different font?") %>% 
  as_flex_table() %>%
  apa_theme() %>%
  flextable::save_as_docx(path = "~/Desktop/weird_table.docx")

Image of table here.


Solution

  • I was able to achieve the desired result by using flextable::add_header_lines instead of gtsummary::modify_caption and by revising apa_theme().

    library(tidyverse)
    library(gtsummary)
    library(flextable)
    
    # theme based on https://github.com/idea-labs/comsldpsy
    apa_theme <- function (ft)  {
      ft %>% 
        flextable::font(fontname = "Times New Roman", part = "all") %>% 
        flextable::fontsize(size = 12, part = "all") %>% 
        flextable::align(align = "left", part = "body") %>% 
        flextable::align(align = "center", part = "header") %>% 
        flextable::rotate(rotation = "lrtb", align = "top", part = "body") %>% 
        flextable::border_remove() %>% 
        flextable::hline_top(border = officer::fp_border(width = 2), 
                             part = "all") %>% 
        flextable::hline_bottom(border = officer::fp_border(width = 2),
                                part = "all") %>% 
        flextable::hline(i = 1, border = officer::fp_border(width = 1), part = "header") %>%
        flextable::set_table_properties(layout = "autofit")
    }
    
    m1 <- lm(response ~ trt, data = trial) %>% tbl_regression()
    m2 <- lm(response ~ trt + marker, data = trial) %>% tbl_regression()
    m3 <- lm(response ~ trt + marker + age, data = trial) %>% tbl_regression()
    
    tbl_merge(
      tbls = list(m1, m2, m3)) %>%
      modify_table_styling(align = "left") %>%
      as_flex_table() %>%
      add_header_lines(values = "Table looks better overall", top = TRUE) %>%
      apa_theme() %>%
      flextable::save_as_docx(path = "~/Desktop/good_table.docx")
    

    Image of good table.