rr-flextable

How can I reorder a flextable's headers when using tabulator() in R?


Here is the current flextable:

enter image description here

Here is the general example data:

enter image description here

library(flextable)

dat <- data.frame(question = c("Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction"),
                 column_one = c("Portion Size", "Portion Size", "Portion Size", "Portion Size", "Portion Size", "Portion Size", "Region", "Region", "Region", "Region"),
                 column_one_order = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2),
                 column_two = c("Small", "Medium", "Large", "Small", "Medium", "Large", "West", "East", "West", "East"),
                 column_two_order = c(1, 2, 3, 1, 2, 3, 1, 2, 1, 2),
                 row_name = c("Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food"),
                 row = c("Pizza", "Pizza", "Pizza", "Hamburger", "Hamburger", "Hamburger", "Pizza", "Pizza", "Hamburger", "Hamburger"),
                 percent = c(0.83679353, 0.341159874, 0.084278807, 0.071733007, 0.363397833, 0.405083242, 0.094760815, 0.762002269, 0.782725923, 0.657853129),
                 standardError = c(0.824884898, 0.69073481, 0.664255159, 0.099570678, 0.735837865, 0.940523571, 0.933454698, 0.669219927, 0.669924278, 0.537262473))

dat

cft <- tabulator(
  x = dat,
  rows = "row",
  columns = c("question", "column_one","column_two"),
  `P` = as_paragraph(percent),
  `SE` = as_paragraph(standardError)
)

ft <- as_flextable(cft)
ft

Is there a parameter or a method where I can rearrange the header based on columns: [column_one_order] and [column_two_order]? So I would want to see Portion Size before Region (which flextable automatically does) and below that would be Small, Medium, Large and then West and East.

My understanding is that tabulator() is automatically arranging it alphabetically when I would like to have it in a more specific order.


Solution

  • You can control orders by using factor instead of characters (as with ggplot2 or table), in that case factor levels are used as order and not alphabetical order:

    library(flextable)
    
    dat <- data.frame(
      question = c("Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction", "Food Satisfaction"),
      column_one = c("Portion Size", "Portion Size", "Portion Size", "Portion Size", "Portion Size", "Portion Size", "Region", "Region", "Region", "Region"),
      column_one_order = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2),
      column_two = c("Small", "Medium", "Large", "Small", "Medium", "Large", "West", "East", "West", "East"),
      column_two_order = c(1, 2, 3, 1, 2, 3, 1, 2, 1, 2),
      row_name = c("Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food", "Food"),
      row = c("Pizza", "Pizza", "Pizza", "Hamburger", "Hamburger", "Hamburger", "Pizza", "Pizza", "Hamburger", "Hamburger"),
      percent = c(0.83679353, 0.341159874, 0.084278807, 0.071733007, 0.363397833, 0.405083242, 0.094760815, 0.762002269, 0.782725923, 0.657853129),
      standardError = c(0.824884898, 0.69073481, 0.664255159, 0.099570678, 0.735837865, 0.940523571, 0.933454698, 0.669219927, 0.669924278, 0.537262473)
    )
    
    dat
    dat$column_one <- factor(dat$column_one, levels = c("Portion Size", "Region"))
    dat$column_two <- factor(dat$column_two, levels = c("Small", "Medium", "Large", "West", "East"))
    cft <- tabulator(
      x = dat,
      rows = "row",
      columns = c("question", "column_one", "column_two"),
      `P` = as_paragraph(percent),
      `SE` = as_paragraph(standardError)
    )
    
    ft <- as_flextable(cft)
    ft
    

    enter image description here