简体   繁体   中英

Flextable: repeat headers without changing column class

For very long tables, it can be useful to repeat headers for better visibility. One could do it manually beforehand on the dataframe by using names() and making that new column with tibble::add_row for example.

However, the issue is that columns need to be of the same class, so if you want to add the column names, you have to transform your columns to character, which in turn prevents flextable from properly formatting numbers.

Function add_body() is the closest thing to my needs ( https://davidgohel.github.io/flextable/reference/add_body.html ). It precisely allows you to add new rows in the body of the table. However, it doesn't allow you to choose on which row you want it added exactly (like tibble::add_row does); there are only two options: top or bottom. Additionally, for the new row, one must specify each cell/column individually, so we cannot rely on names() .

Is there any way to accomplish what I am describing? Thank you.

Edit: Even with add_body() I am getting an error adding a new row with different class, in this case with dates:

Error in as.POSIXlt.character(x, tz, ...) : 
  character string is not in a standard unambiguous format

Indeed, as written in the documentation:

It is important to insert data of the same type as the original data, otherwise it will be transformed (probably into strings if you add a character' where a double' is expected). This keeps the ability to format cell contents with the colformat_* functions, for example colformat_num().

Edit: my best workaround is this:

library(dplyr)
library(flextable)
ft <- flextable(head(iris))
ft %>%
    add_footer_row(values = names(iris),
                   colwidths = rep(1, length(names(iris))))

Although the extra row lies at the bottom, it is still better than not having this information show again.

Edit 2022-01-06:

It seems @jrcalabrese's solution works well for the sample data I provided ( iris dataset). Here is a demonstration that it works even with different column classes (such as date, numeric) and conditional formatting.

library(dplyr)
library(flextable)
iris2 <- cbind(iris, date = as.Date("2021-01-06"))
head(iris2) %>%
    mutate(across(everything(), as.character)) %>%
    add_row(Sepal.Length = "Sepal.Length", 
            Sepal.Width = "Sepal.Width",
            Petal.Length = "Petal.Length",
            Petal.Width = "Petal.Width",
            Species = "Species",
            date = "date", .before = 4) %>%
    flextable() -> ft2
ft2
ft2 %>%
    bg(i = ~ Petal.Length < 1.5,
       j = ft2$col_keys,
       bg = "grey")

在此处输入图像描述

Unfortunately, as mentioned by @jrcalabrese, it is not possible to automatize this process using names() , so we have to define each row name manually.

There is probably a better way to do this, but I think it satisfies your requirements. It involves converting it to a huxtable and then a flextable but unfortunately the title rows have to be manually added for every nth row. You could also suggest this as a potential feature on the flextable Github.

library(tidyverse, warn.conflicts = FALSE)
library(flextable, warn.conflicts = FALSE)
library(huxtable, warn.conflicts = FALSE)

head(iris, 15) %>% 
  mutate(across(everything(), as.character)) %>%
  add_row(Sepal.Length = "Sepal.Length", 
          Sepal.Width = "Sepal.Width",
          Petal.Length = "Petal.Length",
          Petal.Width = "Petal.Width",
          Species = "Species", .before = 6) %>%
  add_row(Sepal.Length = "Sepal.Length", 
          Sepal.Width = "Sepal.Width",
          Petal.Length = "Petal.Length",
          Petal.Width = "Petal.Width",
          Species = "Species", .before = 11) %>%
  as_huxtable() %>%
  set_bold(row = 1, col = everywhere) %>% 
  set_bold(row = 7, col = everywhere) %>% 
  set_bold(row = 12, col = everywhere) %>%
  as_flextable() %>% 
  border_outer() %>% 
  border_inner_h()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM