LittleLynx
LittleLynx

Reputation: 1181

How to access the current by-category in a tbl_custom_summary from gtsummary?

I would like to create a customized gtsummary table, where I have to access the number of cases in that group resulting by by.

For example, I would like to calculate the proportion of patients with a response per stage grouped by treatment. Currently I use this workaround, to access the treatment group:

temp_drugname = pull(data%>%select(trt)%>%distinct())

This works only, if there is at least one patient with the current stage in the treatment group. If there is a stage without patients assigned to it, I can't find a way to calculate the correct total.

In the example below, I deleted the cases in group A with stage 1 cancer. The total should be 21, not 54, in order to later-on calculate confidence intervals correctly.

example with wrong total

library(gtsummary)
library(tidyverse)

my_ratio_summary = function (numerator, na.rm = TRUE, conf.level = 0.95) 
{
  function(data, full_data, ...) {
    temp_drugname = pull(data%>%select(trt)%>%distinct())
    if(length(temp_drugname) > 0){
      druggroup_data = full_data%>%filter(trt == temp_drugname)
    }
    else {
      druggroup_data = full_data
    }
    num <- sum(data[[numerator]], na.rm = na.rm)
    denom <- sum(druggroup_data[[numerator]], na.rm = na.rm)
    ratio <- num/denom

    dplyr::tibble(num = num, denom = denom, ratio = ratio)
  }
}

  trial %>%
  filter(!(trt == 'Drug A' & stage == 'T1'))%>%
  tbl_custom_summary(
    include = c("stage"),
    by = "trt",
    stat_fns = ~ my_ratio_summary("response"),
    statistic = ~"{ratio}%, {num}/{denom}",
    digits = ~ c(style_percent, 0, 0)
  )

Upvotes: 1

Views: 101

Answers (1)

stefan
stefan

Reputation: 124128

One option would be to use the additional arguments passed to the custom function via ..., e.g. the first element is a tibble which contains the info about the current groups which can be used to filter full_data for which I use a semi_join. This works even if data does not contain any observations.

In the code below I added a print statement to show the content of ...:

library(gtsummary)
library(tidyverse)

my_ratio_summary <- function(numerator, na.rm = TRUE, conf.level = 0.95) {
  function(data, full_data, ...) {
    
    dots <- list(...)
    
    # Only added to print the content of `dots`
    print(dots)
    
    druggroup_data <- full_data %>% semi_join(dots[[1]], by = dots$by)
    
    num <- sum(data[[numerator]], na.rm = na.rm)
    denom <- sum(druggroup_data[[numerator]], na.rm = na.rm)
    ratio <- num / denom

    dplyr::tibble(num = num, denom = denom, ratio = ratio)
  }
}

trial %>%
  filter(!(trt == "Drug A" & stage == "T1")) %>%
  tbl_custom_summary(
    include = c("stage"),
    by = "trt",
    stat_fns = ~ my_ratio_summary("response"),
    statistic = ~"{ratio}%, {num}/{denom}",
    digits = ~ c(style_percent, 0, 0)
  )
#> [[1]]
#> # A tibble: 1 × 2
#>   trt    stage
#>   <chr>  <fct>
#> 1 Drug A T1   
#> 
#> $variable
#> [1] "stage"
#> 
#> $by
#> [1] "trt"
#> 
#> $type
#> [1] "categorical"
#> 
#> $stat_display
#> [1] "{ratio}%, {num}/{denom}"

...

enter image description here

Upvotes: 1

Related Questions