Skip to content

Commit

Permalink
Merge branch 'main' into 767_sort_filter_hierarchical
Browse files Browse the repository at this point in the history
  • Loading branch information
ddsjoberg authored Dec 18, 2024
2 parents cd484f6 + 7084e3c commit 4d1a4bf
Show file tree
Hide file tree
Showing 75 changed files with 1,542 additions and 661 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: gtsummary
Title: Presentation-Ready Data Summary and Analytic Result Tables
Version: 2.0.4.9001
Version: 2.0.4.9003
Authors@R: c(
person("Daniel D.", "Sjoberg", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-0862-2018")),
Expand Down
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export(label_style_ratio)
export(label_style_sigfig)
export(last_col)
export(matches)
export(modify_abbreviation)
export(modify_caption)
export(modify_cols_merge)
export(modify_column_alignment)
Expand All @@ -164,6 +165,8 @@ export(modify_column_merge)
export(modify_column_unhide)
export(modify_fmt_fun)
export(modify_footnote)
export(modify_footnote_body)
export(modify_footnote_header)
export(modify_header)
export(modify_source_note)
export(modify_spanning_header)
Expand All @@ -182,6 +185,9 @@ export(pkgdown_print.gtsummary)
export(pool_and_tidy_mice)
export(proportion_summary)
export(ratio_summary)
export(remove_abbreviation)
export(remove_footnote_body)
export(remove_footnote_header)
export(remove_row_type)
export(remove_source_note)
export(reset_gtsummary_theme)
Expand Down
10 changes: 10 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# gtsummary (development version)

* Updates to the handling of footnotes. Previously, header footnotes were handled with `modify_footnote()` and `modify_table_styling(footnote)`. It was possible to also include footnotes in the table body with `modify_table_styling(footnote)`, but this was largely a hidden feature. Also confusingly, a special abbreviation footnote was handled with `modify_footnote(abbreviation=TRUE)`.

In this update, we now export separate user-facing functions for each of these with clearer names and scope: `modify_footnote_header()`, `modify_footnote_body()`, and `modify_abbreviation()`. As the names indicate, the `modify_footnote_header()` and `modify_footnote_body()` functions place footnotes in the header and table body. Abbreviations are now treated like source notes and do not have footnote markers associated with them. We also export functions `remove_footnote_header()`, `remove_footnote_body()`, and `remove_abbreviation()` to remove previously assigned footnotes and abbreviations.

Also, multiple footnotes may now reference the same cell in the table or column header by utilizing the `modify_footnote_header(replace=FALSE)`, `modify_footnote_body(replace=FALSE)` argument.

* Previously, source notes were an undocumented feature and only a single source note could be included in a table. We now export `modify_source_note()` and `remove_source_note()` to add and remove any number of source notes. Also, when merging and stacking tables, previously due to the one source note limit, only the first source note was retained. Now all source notes will be included below the resulting table. _This is different behavior compared to previous versions of the package and in rare cases may result in a different source note._ Moreover, `kableExtra` output now supports source notes, where previously they were omitted.

* Language translations have been updated with a handful of missing translations. (#2100)

# gtsummary 2.0.4

### New Features and Functions
Expand Down
12 changes: 3 additions & 9 deletions R/add_ci.R
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
#' include = c(response, grade)
#' ) |>
#' add_ci(pattern = "{stat} ({ci})") |>
#' modify_footnote(everything() ~ NA)
#' remove_footnote_header(everything())
NULL

#' @rdname add_ci
Expand Down Expand Up @@ -293,10 +293,7 @@ brdg_add_ci <- function(x, pattern, statistic, include, conf.level, updated_call
modify_header(
matches("^ci_stat_\\d+$") ~ paste0("**", conf.level * 100, "% ", translate_string("CI"), "**")
) |>
modify_footnote(
matches("^ci_stat_\\d+$") ~ translate_string("CI = Confidence Interval"),
abbreviation = TRUE
)
modify_abbreviation(translate_string("CI = Confidence Interval"))
}
else {
# get the stat column index numbers, eg get the 1 and 2 from stat_1 and stat_2
Expand Down Expand Up @@ -327,10 +324,7 @@ brdg_add_ci <- function(x, pattern, statistic, include, conf.level, updated_call
x <-
cols_merge_expr |>
reduce(\(.x, .y) inject(!!.x %>% !!.y), .init = x) |>
modify_footnote(
all_stat_cols() ~ translate_string("CI = Confidence Interval"),
abbreviation = TRUE
)
modify_abbreviation(translate_string("CI = Confidence Interval"))

# updating header using `pattern=` argument
x$table_styling$header <-
Expand Down
12 changes: 9 additions & 3 deletions R/add_overall.R
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,16 @@ add_overall_merge <- function(x, tbl_overall, last, col_label, calling_fun) {
}

# updating table_style with footnote and column header
x$table_styling$footnote <-
x$table_styling$footnote_header <-
dplyr::bind_rows(
x$table_styling$footnote,
tbl_overall$table_styling$footnote %>%
x$table_styling$footnote_header,
tbl_overall$table_styling$footnote_header %>%
dplyr::filter(.data$column %in% "stat_0")
)
x$table_styling$footnote_body <-
dplyr::bind_rows(
x$table_styling$footnote_body,
tbl_overall$table_styling$footnote_body %>%
dplyr::filter(.data$column %in% "stat_0")
)

Expand Down
2 changes: 1 addition & 1 deletion R/add_p.tbl_cross.R
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ add_p.tbl_cross <- function(x,
# report p-value as source note ----------------------------------------------
if (source_note == TRUE) {
test_name <-
x$table_styling$footnote |>
x$table_styling$footnote_header |>
dplyr::filter(.data$column %in% "p.value") |>
dplyr::pull("footnote")

Expand Down
6 changes: 3 additions & 3 deletions R/add_significance_stars.R
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#' hide_ci = TRUE, hide_se = TRUE
#' ) |>
#' modify_header(estimate = "**Beta (95% CI)**") |>
#' modify_footnote(estimate = "CI = Confidence Interval", abbreviation = TRUE)
#' modify_abbreviation("CI = Confidence Interval")
#'
#' # Example 3 ----------------------------------
#' # Use ' \n' to put a line break between beta and SE
Expand All @@ -49,7 +49,7 @@
#' pattern = "{estimate}{stars} \n({std.error})"
#' ) |>
#' modify_header(estimate = "**Beta \n(SE)**") |>
#' modify_footnote(estimate = "SE = Standard Error", abbreviation = TRUE) |>
#' modify_abbreviation("SE = Standard Error") |>
#' as_gt() |>
#' gt::fmt_markdown(columns = everything()) |>
#' gt::tab_style(
Expand Down Expand Up @@ -118,7 +118,7 @@ add_significance_stars <- function(x,
unlist() |>
paste(collapse = "; ")

x <- modify_footnote(x, any_of(pattern_cols[1]) ~ p_footnote)
x <- modify_footnote_header(x, footnote = p_footnote, columns = any_of(pattern_cols[1]))

# adding stars column --------------------------------------------------------
thresholds <- union(thresholds, 0L)
Expand Down
2 changes: 1 addition & 1 deletion R/add_stat.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#'
#' - Use `modify_header()` to update the column headers
#' - Use `modify_fmt_fun()` to update the functions that format the statistics
#' - Use `modify_footnote()` to add a explanatory footnote
#' - Use `modify_footnote_header()` to add a explanatory footnote
#'
#' If you return a tibble with column names `p.value` or `q.value`, default
#' p-value formatting will be applied, and you may take advantage of subsequent
Expand Down
105 changes: 66 additions & 39 deletions R/as_flex_table.R
Original file line number Diff line number Diff line change
Expand Up @@ -206,47 +206,84 @@ table_styling_to_flextable_calls <- function(x, ...) {
# autofit --------------------------------------------------------------------
flextable_calls[["autofit"]] <- expr(flextable::autofit())

# footnote -------------------------------------------------------------------
# footnote_header ------------------------------------------------------------
df_footnote_header <-
.number_footnotes(x, "footnote_header") |>
tidyr::nest(df_location = c("column", "column_id")) |>
dplyr::mutate(
column_id = map(.data$df_location, ~ getElement(.x, "column_id"))
)
header_i_index <- ifelse(any_spanning_header == TRUE, 2L, 1L)

df_footnote <-
.number_footnotes(x) |>
dplyr::inner_join(
x$table_styling$header |>
dplyr::select("column", column_id = "id"),
by = "column"
) |>
dplyr::mutate(
row_numbers =
ifelse(.data$tab_location == "header",
header_i_index,
.data$row_numbers
flextable_calls[["footnote_header"]] <-
map(
seq_len(nrow(df_footnote_header)),
~ expr(
flextable::footnote(
i = !!header_i_index,
j = !!df_footnote_header$column_id[[.x]],
value = flextable::as_paragraph(!!df_footnote_header$footnote[[.x]]),
part = "header",
ref_symbols = !!df_footnote_header$footnote_id[[.x]]
)
) |>
dplyr::select(
"footnote_id", "footnote", "tab_location",
"row_numbers", "column_id"
) |>
tidyr::nest(location_ids = c("row_numbers", "column_id")) %>%
)
)

# footnote_body --------------------------------------------------------------
df_footnote_body <-
.number_footnotes(x, "footnote_body", start_with = nrow(df_footnote_header)) |>
tidyr::nest(df_location = c("column", "column_id", "row_numbers")) |>
dplyr::mutate(
row_numbers = map(.data$location_ids, ~ getElement(.x, "row_numbers")),
column_id = map(.data$location_ids, ~ getElement(.x, "column_id"))
row_numbers = map(.data$df_location, ~ getElement(.x, "row_numbers")),
column_id = map(.data$df_location, ~ getElement(.x, "column_id"))
)

flextable_calls[["footnote"]] <-
flextable_calls[["footnote_body"]] <-
map(
seq_len(nrow(df_footnote)),
seq_len(nrow(df_footnote_body)),
~ expr(
flextable::footnote(
i = !!df_footnote$row_numbers[[.x]],
j = !!df_footnote$column_id[[.x]],
value = flextable::as_paragraph(!!df_footnote$footnote[[.x]]),
part = !!df_footnote$tab_location[[.x]],
ref_symbols = !!df_footnote$footnote_id[[.x]]
i = !!df_footnote_body$row_numbers[[.x]],
j = !!df_footnote_body$column_id[[.x]],
value = flextable::as_paragraph(!!df_footnote_body$footnote[[.x]]),
part = "body",
ref_symbols = !!df_footnote_body$footnote_id[[.x]]
)
)
)


# abbreviation ---------------------------------------------------------------
flextable_calls[["abbreviations"]] <-
case_switch(
nrow(x$table_styling$abbreviation) > 0L ~
expr(
flextable::add_footer_lines(
value = flextable::as_paragraph(
!!(x$table_styling$abbreviation$abbreviation |>
paste(collapse = ", ") %>%
paste0(
ifelse(nrow(x$table_styling$abbreviation) > 1L, "Abbreviations", "Abbreviation") |> translate_string(),
": ", .
))
)
)
),
.default = list()
)

# source note ----------------------------------------------------------------
# in flextable, this is just a footnote associated without column or symbol
flextable_calls[["source_note"]] <-
map(
seq_len(nrow(x$table_styling$source_note)),
\(i) {
expr(
flextable::add_footer_lines(value = flextable::as_paragraph(!!x$table_styling$source_note$source_note[i]))
)
}
)

# fmt_missing ----------------------------------------------------------------
df_fmt_missing <-
x$table_styling$fmt_missing |>
Expand Down Expand Up @@ -315,17 +352,7 @@ table_styling_to_flextable_calls <- function(x, ...) {
))
)

# source note ----------------------------------------------------------------
# in flextable, this is just a footnote associated without column or symbol
flextable_calls[["source_note"]] <-
map(
seq_len(nrow(x$table_styling$source_note)),
\(i) {
expr(
flextable::add_footer_lines(value = flextable::as_paragraph(!!x$table_styling$source_note$source_note[i]))
)
}
)


# border ---------------------------------------------------------------------
flextable_calls[["border"]] <-
Expand Down
Loading

0 comments on commit 4d1a4bf

Please sign in to comment.