Reputation: 1181
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.
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
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}"
...
Upvotes: 1