Add add_hierarchical_zero_rows() for unobserved hierarchical levels - #609
Add add_hierarchical_zero_rows() for unobserved hierarchical levels#609Melkiades wants to merge 5 commits into
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.
| #' @param variables ([`tidy-select`][dplyr::dplyr_tidy_select])\cr | ||
| #' the hierarchical variables used to create `x`, in the same order. The first | ||
| #' variable is the top level; the second, when present, is the nested child. | ||
| #' @param mapping (named `list` or `data.frame`)\cr |
There was a problem hiding this comment.
I was thinking a bit more about this. Would the named list require positional matching to the variables added in ard_hierarcihcal(variables, include)? If so, that is probably not the best, and providing a data frame is more robust.
There was a problem hiding this comment.
Do we have a way to handle a situation like:
ard <- ard_heirarchical(variables = c(AESOC, AEPT), include = AEPT)
add_zero_rows(ard, ....) # how do we know to only add the AEPT zeros and not the AESOC?There was a problem hiding this comment.
Both of these were from before I reworked the API, and I think the new version resolves them.
It's now driven by variables instead of the mapping, you name which levels or level to complete, and it reads the expected levels straight from the stored factor levels(). So your include = AEPT case works directly:
ard <- ard_stack_hierarchical(adae, variables = c(AESOC, AEPT), include = AEPT, ...)
# completes only PT — AESOC is left untouched
add_hierarchical_unobserved_levels(ard, variables = AEPT) # TODO: find a good name ahahNothing is positional: variables is tidy-selected by name against the ARD, and the (now optional) mapping list is keyed by parent-level value, not variable order. mapping is only needed for the one thing factor levels can't express: children under a parent that itself never occurs.
So for the common cases there's no data-frame requirement. factor levels cover them. If needed you can add a data.frame too. Do you still want the data.frame form as the primary documented input, or is factor-levels-first fine with you?
There was a problem hiding this comment.
I like more the mapping list as it looks intuitive to me ^^
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!! |
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