merging two gt tables

Hi,

I made two gt tables representing different cell types and corresponding p-values from different models. My supervisor asked me to remove the descriptive spanner labels and merge the two tables. My tables look like this:

table1


table2

I was asked to make this table:

I tried using the {datapasta} package to provide some data, but the Rdata objects are formatted as gt objects. Is there another way I can provide the data?

Secondly, I tried to add a group row label underneath Covariates, and received the following error:

gt_tbl <- table1 %>%
  gt(rowname_col = "Covariates") %>%
  tab_row_group(
    label = "All cases (N = 333) versus controls (N = 396)",
    rows = 2:3
  )

gt_tbl

Error in tab_row_group(., label = "All cases (N = 333) versus controls (N = 396)", :
unused argument (label = "All cases (N = 333) versus controls (N = 396)")

Finally, I would like to merge the two tables. Can I call two different datasets when creating a gt table? I would love some guidance here.

Thank you!

Hello,

Here is a way to do what you are asking. Since I was not able to use your data, I created similar dummy data

library(gt)

#Base tables
table1 = data.frame(
  covariates = LETTERS[1:2],
  Mono = runif(2),
  Neu = runif(2)
)

table2 = data.frame(
  covariates = LETTERS[1:2],
  Mono = runif(2),
  Neu = runif(2)
)

#If the individual tables are a GT object already, exact the data
gtTable = gt(table1)
table1 = gtTable$`_data`


#Merge tables by row
fullTable = rbind(table1, table2)
fullTable
#> # A tibble: 4 x 3
#>   covariates  Mono    Neu
#>   <chr>      <dbl>  <dbl>
#> 1 A          0.296 0.225 
#> 2 B          0.123 0.747 
#> 3 A          0.940 0.721 
#> 4 B          0.206 0.0611

#Create the gt object again for the merged table
gtTable = gt(fullTable) %>%
  tab_row_group(
    group = "Label 1",
    rows = 1:2
  ) %>% 
  tab_row_group(
    group = "Label 2",
    rows = 3:4
  )

gtTable
#> Warning in min(rows_matched): no non-missing arguments to min; returning Inf
#> Warning in max(rows_matched): no non-missing arguments to max; returning -Inf

image

Created on 2021-05-11 by the reprex package (v2.0.0)

Merging tables is very easy using the rbind() function. This is however only possible for normal data frames, so if you have individual gt objects, you first need to extract the original data, merge it and then create the table again (all shown in code above)

You can ignore the last warning message, this is a bug they are working on it seems

Hope this helps,
PJ

1 Like

Thank you very much! I recognised that I needed to rbind() the two tables and was dreading having to go backwards several steps. I will try your suggestion of extracting the data and let you know.

Hi, Sorry that I bumped into trouble already.

Hi,

Could you create a reprex so I can work with the same code / data you are working with? A reprex consists of the minimal code and data needed to recreate the issue/question you're having. You can find instructions how to build and share one here:

Also, try to run my example and see if that works. You should be able to work from there...

PJ

Hi PJ,
I went back to the original data for the tables and used rbind() to get a full table.

datapasta::dpasta(modelstibble::tribble(
                                                               ~Covariates,              ~Mono,                 ~Neu,                ~NK,               ~CD4T,               ~CD8T,              ~Bcell,
                                            "Age, sex, smoking, technical",  0.628417355082566, 0.000519604887456513, 0.0925500673787777, 0.00584722383176443, 0.00110636778126264, 0.00448981271134747,
                           "Age, sex, smoking, technical, blood-draw time",  0.776347680248465,  0.00333944782506215,  0.286264314573566,  0.0186336833741003, 0.00974265172264351,  0.0260571208261442,
                                            "Age, sex, smoking, technical",  0.126203612800461,   0.0069822247870482,  0.898970562719821, 0.00124800394720716,   0.237536193109084,    0.24719207837134,
                           "Age, sex, smoking, technical, blood-draw time", 0.0602578745322921,   0.0110018346892553,  0.772246388504049, 0.00191661864623293,   0.339897214377786,   0.310222407363504
                           )
)

Nice code for the p-value stars courtesy of statistishdan :slight_smile:


# function to round p-value and append stars
add_stars <- function(x, decimals = 3) {
  # create vector of stars
  x_stars <-
    dplyr::case_when(
      x >= 0.05 ~ "",
      x >= 0.01 ~ "*",
      x >= 0.001 ~ "**",
      TRUE ~ "***"
    )
  
  # paste together rounded p-value and stars
  paste0(
    gtsummary::style_number(x, digits = decimals),
    x_stars
  )
}

# gt function to round p-values and add stars
fmt_stars <- function(data,
                      columns,
                      rows = NULL,
                      decimals = 3) {
  
  fmt(
    data = data,
    columns = {{ columns }},
    rows = {{ rows }},
    fns = purrr::partial(add_stars, decimals = decimals)
  )
}

table <- gt(models) %>%
  fmt_stars(columns = 2:7, decimals = 3) %>% 
    cols_align(
    align = "left")



table

Adding the row labels courtesy of you.

library(gt)
gtTable = gt(table) %>%
  tab_row_group(
    group = "All cases (N = 333) versus controls (N = 396)",
    rows = 1:2
  ) %>% 
  tab_row_group(
    group = "Medication-free cases (N = 51) versus controls (N = 315)",
    rows = 3:4
  )

gtTable

But I get this error code:
Error in UseMethod("group_vars") : no applicable method for 'group_vars' applied to an object of class "c('gt_tbl', 'list')"

Thanks again for your help.
Jonelle

Hi,

Now it seems that your data is already in one table... So here is the integration with the new code you provided

library(tidyverse)
library(gt)
library(gtsummary)

#THE DATA (already merged)
models = tribble(
  ~Covariates,              ~Mono,                 ~Neu,                ~NK,               ~CD4T,               ~CD8T,              ~Bcell,
  "Age, sex, smoking, technical",  0.628417355082566, 0.000519604887456513, 0.0925500673787777, 0.00584722383176443, 0.00110636778126264, 0.00448981271134747,
  "Age, sex, smoking, technical, blood-draw time",  0.776347680248465,  0.00333944782506215,  0.286264314573566,  0.0186336833741003, 0.00974265172264351,  0.0260571208261442,
  "Age, sex, smoking, technical",  0.126203612800461,   0.0069822247870482,  0.898970562719821, 0.00124800394720716,   0.237536193109084,    0.24719207837134,
  "Age, sex, smoking, technical, blood-draw time", 0.0602578745322921,   0.0110018346892553,  0.772246388504049, 0.00191661864623293,   0.339897214377786,   0.310222407363504
)


#FUNCTIONS
# function to round p-value and append stars
add_stars <- function(x, decimals = 3) {
  # create vector of stars
  x_stars <-
    dplyr::case_when(
      x >= 0.05 ~ "",
      x >= 0.01 ~ "*",
      x >= 0.001 ~ "**",
      TRUE ~ "***"
    )
  
  # paste together rounded p-value and stars
  paste0(
    gtsummary::style_number(x, digits = decimals),
    x_stars
  )
}

# gt function to round p-values and add stars
fmt_stars <- function(data,
                      columns,
                      rows = NULL,
                      decimals = 3) {
  
  fmt(
    data = data,
    columns = {{ columns }},
    rows = {{ rows }},
    fns = purrr::partial(add_stars, decimals = decimals)
  )
}

#THE GT TABLE
gt(models) %>%
  fmt_stars(columns = 2:7, decimals = 3) %>% 
  cols_align(
    align = "left") %>%
  tab_row_group(
    group = "All cases (N = 333) versus controls (N = 396)",
    rows = 1:2
  ) %>% 
  tab_row_group(
    group = "Medication-free cases (N = 51) versus controls (N = 315)",
    rows = 3:4
  ) %>% 
  tab_style(
    style = list(
      cell_fill(color = "lightgray")
    ),
    locations = cells_row_groups()
  )

Created on 2021-05-11 by the reprex package (v2.0.0)
image

I also added the code for making the row headers gray like you showed in the first post.

PJ

1 Like

Wonderful! It was good to learn about the tab_style function. Thank you for that. It is curious that the output shows the groups in reverse order to the code. I will try and switch them. gt is a really great and the new gt Cookbook is precious.

Hi,

You're welcome.

Yes it was the first time for me as well working with the gt package. I think it has some nice ideas, but indeed it's not mature yet. That switching is one of them, also that warning and some of the documentation seems to be outdated. Hopefully they will keep on working on it.

PJ

1 Like