Search code examples
rr-markdownflextable

How to re-format flextable after using delete_columns?


I am trying to generate a flextable (Rmarkdown to Word) from a table object without the extra columns that come with "as_flextable.table". Here is what I have so far:

xt<- xtabs(~mpg + cyl, head(mtcars))
ft<- as_flextable(xt, include.row_percent = FALSE, include.column_percent = FALSE, include.table_percent = FALSE)
ft

enter image description here

From that I can use "delete_rows" and "delete_columns" to remove the "Total" row and column.

ft<- delete_rows(ft, i = 6, part = "body")
ft<- delete_columns(ft, j = 5)

But this messes up the formatting and I do not know how to get it back. formatting is messed up after using 'delete_columns'

How can I get back to the original formatting, where "cyl" spans the cylinder columns and there is only one 'mpg' heading?


Solution

  • Here is one option to achieve your desired result:

    1. Re-Merge the header rows and columns using merge_v and merge_h
    2. Re-Set the bottom border line
    3. Remove the right border line
    4. Finally, run fix_border_issues.
    library(flextable)
    
    xt <- xtabs(~ mpg + cyl, head(mtcars))
    ft <- as_flextable(xt,
      include.row_percent = FALSE,
      include.column_percent = FALSE,
      include.table_percent = FALSE
    )
    
    ft <- delete_rows(ft, i = 6, part = "body")
    ft <- delete_columns(ft, j = 5)
    
    ft <- flextable::merge_v(ft, j = 1, part = "header")
    ft <- flextable::merge_h(ft, i = 1, part = "header")
    
    # Add bottom border
    ft <- hline_bottom(ft,
      j = seq_len(ncol_keys(ft)),
      border = officer::fp_border(
        color = "#666666",
        width = 1.5
      )
    )
    # Remove right border
    ft <- vline_right(ft,
      i = seq_len(nrow_part(ft, "body")),
      border = officer::fp_border(width = 0),
      part = "body"
    )
    ft <- vline_right(ft,
      i = seq_len(nrow_part(ft, "header")),
      border = officer::fp_border(width = 0),
      part = "header"
    )
    # Fix border issues
    ft <- flextable::fix_border_issues(ft)
    ft
    

    enter image description here

    EDIT Here is a possible approach for a custom function:

    my_flextable <- function(xt) {
      ft <- as_flextable(xt,
        include.row_percent = FALSE,
        include.column_percent = FALSE,
        include.table_percent = FALSE
      )
      
      ft <- delete_rows(ft, i = nrow_part(ft, part = "body"), part = "body")
      ft <- delete_columns(ft, j = ncol_keys(ft))
    
      ft <- flextable::merge_v(ft, j = 1, part = "header")
      ft <- flextable::merge_h(ft, i = 1, part = "header")
    
      # Add bottom border
      ft <- hline_bottom(ft,
        j = seq_len(ncol_keys(ft)),
        border = officer::fp_border(
          color = "#666666",
          width = 1.5
        )
      )
      # Remove right border
      ft <- vline_right(ft,
        i = seq_len(nrow_part(ft, "body")),
        border = officer::fp_border(width = 0),
        part = "body"
      )
      ft <- vline_right(ft,
        i = seq_len(nrow_part(ft, "header")),
        border = officer::fp_border(width = 0),
        part = "header"
      )
      # Fix border issues
      ft <- flextable::fix_border_issues(ft)
      ft
    }