Conversation
Stacked hierarchical ARDs include only observed levels because the tabulation routes through the strata (observed-only) branch, so predefined categories such as SMQ/CQ baskets, SOCs, and preferred terms disappear instead of showing a zero count. add_hierarchical_zero_rows() appends zero-count rows for unobserved levels using a mapping of the expected level universe. A single mapping argument (named list or data.frame) covers both an unobserved top-level category and an unobserved child of an observed parent, and preserves the by structure and denominators so percentages remain correct.
What do you mean by percentages stay correct? |
Read the expected level universe from the factor levels the ARD already carries, so top-level and nested completion need only `variables`. `mapping` becomes optional and additive, used only for children of an unobserved parent or a bespoke universe that factor levels cannot express.
Rename the function (and its file/tests/docs) to add_hierarchical_unobserved_levels(), matching the intent of adding unobserved factor levels rather than raw zero-rows. Drop the user-facing `statistic` argument; the count-style stats are zeroed internally while denominators carry over, so callers no longer manage that detail. Rewrite the documentation to lead with the single-variable case and cross-link gtsummary::tbl_hierarchical() so users can discover it.
A never-observed level has no one at risk, so its proportion is 0 / 0 -- undefined, not zero. Set only the counts (n, n_cum) to zero and leave p/p_cum as NaN, letting the display layer recode them rather than asserting zero in the ARD.
I was mapping it to 0 which is wrong. now for an added unobserved level the proportion is 0 / 0, which is undefined ,so I leave p/p_cum as NaN rather than asserting 0 in the ARD. The "show as 0" is a display choice and gets recoded downstream, so the ARD stays correct!! |
Replace the factor-level reading and the named-list mapping with a single levels data frame whose columns are named after the hierarchical variables. This removes the positional matching, drops the reliance on factor levels, and treats every level of the hierarchy the same way: a newly added parent gets its full child set through the same code path as an observed parent.
pkgdown requires every exported topic to be indexed; the new function was missing from _pkgdown.yml, failing the docs build.
| #' recoded for display rather than asserted as zero here. | ||
| #' | ||
| #' @param x (`card`)\cr | ||
| #' a stacked hierarchical ARD created with [ard_stack_hierarchical()]. |
There was a problem hiding this comment.
Should this work with the counting variant as well?
| #' Use a single column (e.g. just `AESOC`) to complete only the top level. | ||
| #' | ||
| #' @return a stacked hierarchical ARD | ||
| #' @seealso [gtsummary::tbl_hierarchical()], [ard_stack_hierarchical()], [sort_ard_hierarchical()] |
There was a problem hiding this comment.
I would take these out. They are essentially internal helpers [gtsummary::tbl_hierarchical()], [ard_stack_hierarchical()]
| #' | ||
| #' @examples | ||
| #' set.seed(1) | ||
| #' adae <- data.frame( |
There was a problem hiding this comment.
we don't simulate our AE datasets in the other examples. why did you choose to do it here?
| .hierarchical_zero_stats <- c("n", "n_cum") | ||
| .hierarchical_nan_stats <- c("p", "p_cum") |
There was a problem hiding this comment.
what happens if a user has the cum counts/percentage in the source table?
| @@ -0,0 +1,180 @@ | |||
| skip_on_cran() | |||
There was a problem hiding this comment.
Claude is notorious for over-testing, or not quite testing the things that matter the most to us. Can you confirm you have reviewed each of these manually and agree with all the tests added and do not see any missing tests?
Adds
add_hierarchical_zero_rows(), an ARD-level helper that appends zero-count rows for unobserved hierarchical levels using amappingof the expected level universe.A single
mappingargument (named list or two-column data.frame) covers:Preserves the
bystructure and carries denominators over so percentages stay correct (p = 0, no NaN).closes #602