-
Notifications
You must be signed in to change notification settings - Fork 130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom table #973
Comments
A sort of
If a continuous variable is passed to Such a @ddsjoberg, what do you think? |
Not super easy, for sure! Users could easily merge results from a univariate Poisson regression, for example, to get those rates in a table. They could also use a custom function with
I think I need to see an example of how |
Just thinking and trying to mature the idea.
I have seen In term of concepts, Maybe to be more consistent with other gtsummary function, that custom function would return a list of stats, and the user will have to provide a pattern, and the styling will be manage as usual. So a concept example could be: my_fun <- function(data) {
num <- sum(data$cases)
denom <- sum(data$observation_time)
list(num = num, denom = denom, ratio = num / denom)
}
data %>%
tbl_custom(
include = group,
by = sex,
stat_fun = my_fun,
pattern = "{ratio} ({num}/{denom})",
digits = c(2, 1, 1)
)
|
To allow most of the customization, it should of course be possible to return character values in |
@larmarange nice, it's taking me some time to digest the suggestion. We're in agreement that we should have support/helper functions to construct custom tables. Whatever we decide to implement will need follow the existing framework of a gtsummary table outlined here: https://www.danieldsjoberg.com/gtsummary/dev/articles/gtsummary_definition.html So this custom function will also have enough information to construct the internals. Here's how I would construct the table with library(gtsummary)
ratio_fun <- function(data, variable, by, tbl = NULL, ...) {
data %>%
dplyr::group_by_at(c(variable, by)) %>%
dplyr::summarize(
num = sum(death, na.rm = TRUE),
denom = sum(ttdeath, na.rm = TRUE),
ratio = num / denom,
.groups = "drop"
) %>%
dplyr::mutate(
dplyr::across(all_of(c("num", "denom", "ratio")),
style_sigfig),
stat = glue::glue("{ratio} ({num}/{denom})")
) %>%
dplyr::rename(variable = all_of(variable),
by = all_of(by)) %>%
dplyr::left_join(
tbl$df_by %>% select(by, by_col) %>% mutate(by_col = paste0("add_", by_col)),
by = "by"
) %>%
select(all_of(c("variable", "by_col", "stat"))) %>%
tidyr::pivot_wider(
id_cols = all_of("variable"),
values_from = all_of("stat"),
names_from = all_of("by_col")
) %>%
dplyr::arrange(variable) %>%
dplyr::select(-variable)
}
trial %>%
tbl_summary(
by = trt,
include = grade
) %>%
modify_column_hide(all_stat_cols()) %>%
add_stat(fns = everything() ~ ratio_fun,
location = everything() ~ "level") %>%
as_kable()
Created on 2021-08-31 by the reprex package (v2.0.1) |
Perhaps what we need is a For example, trial %>%
select(age, grade) %>%
tbl_base() Then we can use functions like This will ensure the proper internal structure is maintained. |
Thanks @ddsjoberg for your feedback. Sorry I'm currently traveling and do not always have access to Wifi.
Totally agree
That's the thing. There is no rush here but I have the feeling that it would be great to think about both very generic functions but limited to very advanced users, and probably some more limited but easier to implement functions. In any cases, a FAQ where it would be possible to centralise many tricks around |
tbl_base could be a good idea for code mutualisation between different functions. It could even be used for tbl_summary |
It took me some time but I guess that I finally get your point. Using tbl_base and modify_table_body would make the writing of new functions easier and will maintain consistency. Great idea |
I also take your point that Maybe something to bind a tibble you've created to an existing gtsummary table (this would be like a I am still not sure what the best move is. But it's good to have these conversations and let the ideas mature. |
Yes. We clearly need time to mature it. I will try to do some tests as a proof of concept as soon as I find some time |
Dear @ddsjoberg Just to experiment a little, I have drafted a You will also find concrete examples. In fact, instead of creating an empty table and then use |
* draft of tbl_custom_summary fix #973 * document * filter NA values * pass stat_display as well * using dplyr::group_modify instead of summarise * document * cleaning * doc update * experimental * Option for adding an overall row * documentation improvements * better example * documentation updates * Create test-tbl_custom_summary.R * doc updates * Doc update Caution section and not mentionning internal variable * first helper to tbl_custom_summary * Update test-tbl_custom_summary.R * Update test-tbl_custom_summary.R * fix for continuous_summary() * .drop = FALSE when grouping * avoiding .by and .variable * theme elements for tbl_custom_summary() * ratio_summary * proportion_summary() * improved examples * doc update * additional tests for tbl_custom_summary * spell_check * simpler syntax * too long example * misc updates * doc updates Co-authored-by: Daniel Sjoberg <danield.sjoberg@gmail.com>
Do we have an easy way to produce a ratio / incidence table, i.e. a table where we report the ratio between two variables (i.e. a numerator and a denominator)?
It could be part of a more global discussion about producing a table (one-way or two-way) where the content of the cells depends on a custom function applied to other variables (e.g. the sum of a third variable, the ratio of two variables, etc.), applied to subgroups.
Somehow, such a table would depend on (i) a list of categorical variables for rows; (ii) an optional categorical variable display in columns; (iii) a custom function applied on the subsample.
Would it be something worth considering?
The text was updated successfully, but these errors were encountered: