代码之家  ›  专栏  ›  技术社区  ›  Homer Jay Simpson

R中flextable的标题字体和垂直合并

  •  1
  • Homer Jay Simpson  · 技术社区  · 5 月前

    我在R中有一个名为df的数据帧:

    
    library(tidyverse)
    library(officer)
    library(flextable)
    
    df = df%>%
      arrange(
        Category,
        factor(Favor, levels = c("Bad", "Mediocre", "Good")),
        Year
      ) %>%
      pivot_wider(
        names_from = c(Favor, Year),
        values_from = Percentage,
        names_sep = "-"
      )
    
    # Create the flextable
    ft <- flextable(df)
    # Apply conditional formatting
    for (col in names(df)) {
      if (grepl("Bad", col)) {
        # Rows with "Unfavorable" > 30 (Red)
        ft <- color(ft, i = which(df[[col]] > 30), j = col, color = "black")
        ft <- bg(ft, i = which(df[[col]] > 30), j = col, bg = "#ed2e1c")
        
        # Rows with "Unfavorable" between 20 and 30 (Light red)
        ft <- bg(ft, i = which(df[[col]] > 20 & df[[col]] <= 30), j = col, bg = "#e09c95")
      }
      if (grepl("Mediocre", col)) {
        # Rows with "Neutral" > 30 (Blue)
        ft <- color(ft, i = which(df[[col]] > 30), j = col, color = "black")
        ft <- bg(ft, i = which(df[[col]] > 30), j = col, bg = "#85c1e9")
      }
      if (grepl("Good", col)) {
        ft <- color(ft, i = which(df[[col]] > 75), j = col, color = "black")
        ft <- bg(ft, i = which(df[[col]] > 75), j = col, bg = "#04B431")
        ft <- bg(ft, i = which(df[[col]] > 65 & df[[col]] <= 75), j = col, bg = "#7FF98B")
      }
    }
    
    
    custom_border = officer::fp_border(color = "black", width = 1)
    ft
    # Display the flextable with borders and color
    ft %>%
      flextable::border_outer(part = "all", border = custom_border) %>%  # Add outer borders
      flextable::border(i = NULL, j = 1, border.left = custom_border) %>%  # Add left border
      flextable::border(i = NULL, j = ncol(df), border.right = custom_border) %>%  # Add right border
      flextable::hline(border = custom_border, part = "body") %>%  # Add horizontal lines between rows
      flextable::vline(border = custom_border, part = "all") %>%
      flextable::align(j = 2:ncol(df), align = "center", part = "all") %>%
      flextable::set_header_labels(ft,
                                   Category = " ",
                                   "Bad-1998"    = "Bad",
                                   "Bad-1999"    = "Bad",
                                   "Bad-2001"    = "Bad",
                                   "Bad-2002"    = "Bad",
                                   "Mediocre-1998"    = "Mediocre",
                                   "Mediocre-1999"    = "Mediocre",
                                   "Mediocre-2001"    = "Mediocre",
                                   "Mediocre-2002"    = "Mediocre",
                                   "Mediocre-1998"    = "Mediocre",
                                   "Mediocre-1999"    = "Mediocre",
                                   "Mediocre-2001"    = "Mediocre",
                                   "Mediocre-2002"    = "Mediocre") %>%
      add_header_row(values = c("Categories", 
                                "group a",
                                "group b", 
                                "group c"), colwidths = c(1, 4, 4, 4)) %>%
      flextable::color(i = 1, j = 2, color = "#ed2e1c", part = "header") %>%
      flextable::color(i = 1, j = 2, color = "darkgreen", part = "header") %>%
      flextable::bold(part = "header") %>%  # Make the header text bold
      flextable::width(j = 1, width = 2) %>%
      flextable::width(j =  c(2,5,8), width = 1) 
    
    
    

    看起来像附件中的图片。

    问题是,我希望将第一列的前两行合并并命名为“类别”,标题中“组b”的字体为绿色。

    如何使用flextable?

    enter image description here

    数据

    df = structure(list(Year = c(2002, 2002, 2002, 2002, 2002, 2002, 2002, 
                            2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 
                            2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 
                            2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 
                            2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 1998, 1998, 1998, 
                            1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 
                            1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 
                            1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 
                            1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 1998, 
                            1998, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 
                            1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 
                            1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 
                            1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 1999, 
                            1999, 1999, 1999, 1999, 1999, 2001, 2001, 2001, 2001, 2001, 2001, 
                            2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 
                            2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 
                            2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 
                            2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001, 2001), Category = c("A", 
                                                                                                "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D", "E", "E", 
                                                                                                "E", "F", "F", "F", "G", "G", "G", "H", "H", "H", "I", "I", "I", 
                                                                                                "J", "J", "J", "K", "K", "K", "L", "L", "L", "M", "M", "M", "N", 
                                                                                                "N", "N", "O", "O", "O", "P", "P", "P", "A", "A", "A", "B", "B", 
                                                                                                "B", "C", "C", "C", "D", "D", "D", "E", "E", "E", "F", "F", "F", 
                                                                                                "G", "G", "G", "H", "H", "H", "I", "I", "I", "J", "J", "J", "K", 
                                                                                                "K", "K", "L", "L", "L", "M", "M", "M", "N", "N", "N", "O", "O", 
                                                                                                "O", "P", "P", "P", "A", "A", "A", "B", "B", "B", "C", "C", "C", 
                                                                                                "D", "D", "D", "E", "E", "E", "F", "F", "F", "G", "G", "G", "H", 
                                                                                                "H", "H", "I", "I", "I", "J", "J", "J", "K", "K", "K", "L", "L", 
                                                                                                "L", "M", "M", "M", "N", "N", "N", "O", "O", "O", "P", "P", "P", 
                                                                                                "A", "A", "A", "B", "B", "B", "C", "C", "C", "D", "D", "D", "E", 
                                                                                                "E", "E", "F", "F", "F", "G", "G", "G", "H", "H", "H", "I", "I", 
                                                                                                "I", "J", "J", "J", "K", "K", "K", "L", "L", "L", "M", "M", "M", 
                                                                                                "N", "N", "N", "O", "O", "O", "P", "P", "P"), Favor = c("Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", 
                                                                                                                                                        "Bad", "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", 
                                                                                                                                                        "Good", "Mediocre", "Bad", "Good", "Mediocre", "Bad", "Good", 
                                                                                                                                                        "Mediocre", "Bad"), Percentage = c(36.85, 36.88, 46.28, 60.28, 
                                                                                                                                                                                           45.3, 36.42, 70.44, 37.39, 34.17, 58.23, 48.77, 34.99, 67.53, 
                                                                                                                                                                                           33.46, 32.01, 35.96, 35.33, 62.71, 46.84, 32.92, 42.24, 83.21, 
                                                                                                                                                                                           26.67, 16.11, 65.91, 23.94, 46.15, 81.83, 23.86, 27.31, 74.32, 
                                                                                                                                                                                           35.09, 33.59, 71.91, 30.92, 28.17, 62.84, 33.06, 27.1, 63.05, 
                                                                                                                                                                                           44.81, 26.15, 76.68, 35.99, 23.33, 49.19, 34.58, 42.23, 55.21, 
                                                                                                                                                                                           35.37, 34.42, 64.48, 36.53, 33.99, 70.81, 27.1, 31.09, 51.36, 
                                                                                                                                                                                           43, 37.65, 64.57, 34.37, 29.06, 35.55, 28.44, 56.01, 56.84, 33.36, 
                                                                                                                                                                                           38.8, 79.74, 35.74, 22.52, 66.86, 29.99, 44.15, 89.57, 27.79, 
                                                                                                                                                                                           14.64, 82.49, 27.37, 27.14, 75.92, 33.39, 18.69, 69.8, 34.69, 
                                                                                                                                                                                           29.51, 75.2, 42.63, 29.17, 90.33, 36.72, 13.95, 52.73, 30, 38.27, 
                                                                                                                                                                                           68.14, 40.61, 33.25, 66.2, 33.99, 31.81, 80.38, 26.48, 21.13, 
                                                                                                                                                                                           50.5, 40.36, 37.14, 74.17, 31.78, 29.04, 44.91, 35.24, 43.85, 
                                                                                                                                                                                           69.23, 35.44, 32.33, 86.44, 24.11, 17.46, 69.69, 33.06, 40.25, 
                                                                                                                                                                                           86.37, 21.21, 21.42, 80.11, 35.57, 32.32, 77.2, 32.03, 19.77, 
                                                                                                                                                                                           72.98, 28.08, 20.94, 70.81, 29.12, 24.07, 88.14, 22.31, 16.55, 
                                                                                                                                                                                           67.49, 44.16, 32.35, 69.03, 39.45, 28.52, 71.97, 37.6, 25.43, 
                                                                                                                                                                                           79.06, 38.4, 19.55, 68.94, 37.03, 30.03, 80.74, 30.59, 30.67, 
                                                                                                                                                                                           49.07, 45.79, 47.14, 60.1, 27.55, 34.36, 88.54, 30.2, 20.26, 
                                                                                                                                                                                           59.42, 22.98, 43.61, 86.84, 16.73, 14.43, 77.42, 22.07, 22.52, 
                                                                                                                                                                                           78.85, 23.88, 17.28, 78.22, 39.57, 27.22, 80.17, 26.21, 20.63, 
                                                                                                                                                                                           94.63, 28.66, 13.71, 65.86, 31.97, 32.16)), row.names = c(NA, 
                                                                                                                                                                                                                                                     -192L), class = c("tbl_df", "tbl", "data.frame"))
    
    
    
    
    1 回复  |  直到 5 月前
        1
  •  1
  •   stefan    5 月前

    要(垂直)合并单元格,它们必须包含相同的值,即如果要使用 merge_v .

    要着色 "group b" 在绿色中,您必须瞄准第6列,即 “b组” 开始。

    library(tidyverse)
    library(officer)
    library(flextable)
    
    header_labels <- gsub("\\-.+$", "", names(df))
    names(header_labels) <- names(df)
    # Use "Categories" as label to merge the cells
    header_labels[["Category"]] <- "Categories"
    
    custom_border <- officer::fp_border(color = "black", width = 1)
    
    # Display the flextable with borders and color
    ft1 <- ft %>%
      flextable::border_outer(part = "all", border = custom_border) %>% # Add outer borders
      flextable::border(i = NULL, j = 1, border.left = custom_border) %>% # Add left border
      flextable::border(i = NULL, j = ncol(df), border.right = custom_border) %>% # Add right border
      flextable::hline(border = custom_border, part = "body") %>% # Add horizontal lines between rows
      flextable::vline(border = custom_border, part = "all") %>%
      flextable::align(j = 2:ncol(df), align = "center", part = "all") %>%
      flextable::set_header_labels(ft,
        values = header_labels
      ) %>%
      add_header_row(values = c(
        "Categories",
        "group a",
        "group b",
        "group c"
      ), colwidths = c(1, 4, 4, 4)) %>%
      flextable::bold(part = "header") %>% # Make the header text bold
      flextable::width(j = 1, width = 2) %>%
      flextable::width(j = c(2, 5, 8), width = 1)
    
    ft1 |>
      merge_v(j = 1, part = "header") |>
      color(
        i = 1, j = 6,
        color = "darkgreen", part = "header"
      )
    

    enter image description here