Search code examples
rgt

Merge two cells together in gt() in just one row


Is it possible to merge two cells together in a gt table but ONLY one row is affected and no columns are removed.

Here is an img of what I'm describing. In this case, both HIS and GIC have the same kind of insurance:

enter image description here

Here is a simplified version of the table.

library("gt")
library("tidyverse")

df <- tibble(
  desc = c("R1", "R2", "R3"),
  A = c("This is a long sentence that should go over into B's column", "just one cell in colA", "just one cell in colA"),
  B = c("", "just one cell in colB", "just one cell in colB"),
  C = c("just one cell in colC", "just one cell in colC", "just one cell in colC")
)

gt(df)

gt(df) |> 
  cols_merge(
    columns = c(A, B))

ANSWER

Kudos to @MarBlo for a clever solution to answering my question about creating a single merged cell using gt.

However I went with the simpler solution realized by switching to flextable shown below.

There are many table libraries in R. For my use, where the output is HTML, I use reactable for interactivity, gt for static and now flextable for static where merged cells are used.

library("flextable")
library("tidyverse")

df <- tibble(
  desc = c("R1", "R2", "R3"),
  A = c("This is a long sentence that should go over into B's column", "just one cell in colA", "just one cell in colA"),
  B = c("", "just one cell in colB", "just one cell in colB"),
  C = c("just one cell in colC", "just one cell in colC", "just one cell in colC")
)

ft <- flextable(df) |> 
  set_header_labels("desc" = "") |> 
  merge_at(i = 1, j = 2:3)
ft

Solution

  • Maybe this can be a start for you. I have created 2 separate gt - one contains the first row of the DF only and the other the other 2 rows.

    Key is to

    1. store one object as_raw_html()
    2. and add this to the other gt with tab_source_note(source_note = firstTable)

    I have tweaked a little bit with col_width and tab_options for improving the alignment a bit.

    It should by possible to change the order of rows by changing which gt is stored as html and to which this is added-

    library(gt)
    library(dplyr)
    
    df <- tibble(
      desc = c("R1", "R2", "R3"),
      A = c("This is a long sentence that should go over into B's column", "just one cell in colA", "just one cell in colA"),
      B = c("", "just one cell in colB", "just one cell in colB"),
      C = c("just one cell in colC", "just one cell in colC", "just one cell in colC")
    )
    
    firstTable <- df |> 
      filter(desc == "R1") |> 
      mutate(B = NULL) |> 
      gt() |> 
      cols_width(
        desc ~ px(45),
        A ~ px(200),
        everything() ~ px(100)
      ) |> 
      tab_options(column_labels.hidden = TRUE,
                  table.width = px(350),
                  table_body.border.bottom.color = 'white',
                  table_body.border.top.color = "white",
                  table_body.hlines.color = 'white') |> 
      as_raw_html()
      
    
    
    df |> 
      filter(desc != "R1") |> 
      gt() |> 
      cols_width(
        desc ~ px(50),
        A ~ px(100),
        B ~ px(100),
        everything() ~ px(100)
      ) |> 
      tab_options(column_labels.hidden = F,
                  table.width = px(350)) |> 
      tab_source_note(source_note = firstTable)
    

    enter image description here