rflextable

Is there a function in flextable to group a few rows in a table together under a label?


I would like to produce a table in flextable that groups together certain rows

For example using the data:

df<-structure(list(` ` = c("Group", "Age", 
"Residence", "Smoker", "Europe"
), `1` = c("63", "25 ", "25", 
"15", "15"), `2` = c("23", 
"53 ", "53", "74", "11"), 
    `3` = c("85", "22", "43", 
    "13", "15")), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame"))

Make table

df<-flextable(df)  %>%
  add_footer_lines("Observed event") %>%
   color(part = "footer", color = "#800000") %>%
   bold( bold = TRUE,part="header")  %>%
   width(j = NULL, width = 1, unit = "in")  %>%
    autofit() 

I would like to add a grouping row above the smoker and Europe rows, called 'demographics'. With longer tables these groupings make it easier to read. There is something similar in kable (group_rows or pack_rows) but I haven't found one for flextable.

image of current table


Solution

  • There is a function that structure a grouped data.frame where groups are printed as rows separators. So this answer only applies if you have a group that is available in the data.frame. I think the result is the same than the one provided with 'ftExtra', it only differs in the data preparation step.

    I added to the example a column named type to be used for this role.

    library(flextable)
    library(magrittr)
    
    df <- structure(list(
      type = c("glop glop", "glop glop" , "glop glop", "pas glop pas glop", "pas glop pas glop"), 
      what = c("Group", "Age", "Residence", "Smoker", "Europe"), 
      `1` = c(63, 25, 25, 15, 15), 
      `2` = c(23, 53, 53, 74, 11),
      `3` = c(85, 22, 43, 13, 15)
      ), 
      row.names = c(NA, -5L), 
      class = c("data.frame"))
    
    df
    #>                type      what  1  2  3
    #> 1         glop glop     Group 63 23 85
    #> 2         glop glop       Age 25 53 22
    #> 3         glop glop Residence 25 53 43
    #> 4 pas glop pas glop    Smoker 15 74 13
    #> 5 pas glop pas glop    Europe 15 11 15
    
    

    Few default settings:

    set_flextable_defaults(font.color = "#333333", border.color = "#999999", padding = 4)
    

    And now the flextable. First as_grouped_data() to restructure the data.frame, then as_flextable() to turn it as a flextable easily.

    as_grouped_data(df, groups = "type") %>% 
      as_flextable() %>% 
      add_footer_lines("Observed event") %>%
      set_header_labels(what = "") %>% 
      color(part = "footer", color = "#800000") %>%
      bold( bold = TRUE, part="header") %>% 
      align(i = ~ !is.na(type), align = "center") %>% 
      bold(i = ~ !is.na(type))
    

    enter image description here