feat: report suppressed component dollars in the signpost message (#9)
.inform_suggestions() and cog_explain() now render suppressed_amount / suppressed_years / suppressed_codes as a continuation line on each suggestion bullet whenever suppressed_amount > 0 (an empty_year fire can carry them too, so this keys off the amount, not trigger). Also renames the cli header from "Coverage gap detected" to "Incomplete coverage" -- a partial-coverage fire is not a gap, the year has rows, they're just short.
This commit is contained in:
+8
-1
@@ -125,8 +125,15 @@ cog_explain <- function(result, format = c("print", "list")) {
|
|||||||
if (length(prov$suggestions) > 0L) {
|
if (length(prov$suggestions) > 0L) {
|
||||||
cli::cli_h2("Suggestions")
|
cli::cli_h2("Suggestions")
|
||||||
sugg_lines <- vapply(prov$suggestions, function(s) {
|
sugg_lines <- vapply(prov$suggestions, function(s) {
|
||||||
sprintf("%s -- %s (years %s-%s): %s", s$recipe_id, s$label,
|
line <- sprintf("%s -- %s (years %s-%s): %s", s$recipe_id, s$label,
|
||||||
s$available_years[1], s$available_years[2], s$hint)
|
s$available_years[1], s$available_years[2], s$hint)
|
||||||
|
if (isTRUE(s$suppressed_amount > 0)) {
|
||||||
|
line <- paste0(line, sprintf(" [$%s excluded from %s: %s]",
|
||||||
|
formatC(s$suppressed_amount, format = "f", digits = 0, big.mark = ","),
|
||||||
|
paste0("FY", s$suppressed_years, collapse = ", "),
|
||||||
|
paste(s$suppressed_codes, collapse = ", ")))
|
||||||
|
}
|
||||||
|
line
|
||||||
}, character(1))
|
}, character(1))
|
||||||
cli::cli_ul(sugg_lines)
|
cli::cli_ul(sugg_lines)
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -357,12 +357,25 @@
|
|||||||
#' expressions. When a suggestion has an `ig_recipe_id`, one indented
|
#' expressions. When a suggestion has an `ig_recipe_id`, one indented
|
||||||
#' continuation line is appended naming the intergovernmental counterpart
|
#' continuation line is appended naming the intergovernmental counterpart
|
||||||
#' recipe (embedded `\n` renders as a hanging-indent continuation of the
|
#' recipe (embedded `\n` renders as a hanging-indent continuation of the
|
||||||
#' same bullet under cli, not a new bullet).
|
#' same bullet under cli, not a new bullet). Same treatment for
|
||||||
|
#' `suppressed_amount` (uscogdata#9): only present when dollars were
|
||||||
|
#' actually measured as excluded (an `empty_year` fire can carry them too --
|
||||||
|
#' see `.build_suggestions()` -- so this keys off the amount, not `trigger`).
|
||||||
#' @noRd
|
#' @noRd
|
||||||
.inform_suggestions <- function(suggestions) {
|
.inform_suggestions <- function(suggestions) {
|
||||||
bullets <- vapply(suggestions, function(s) {
|
bullets <- vapply(suggestions, function(s) {
|
||||||
bullet <- sprintf("%s (%d-%d): %s", s$recipe_id,
|
bullet <- sprintf("%s (%d-%d): %s", s$recipe_id,
|
||||||
s$available_years[1], s$available_years[2], s$hint)
|
s$available_years[1], s$available_years[2], s$hint)
|
||||||
|
# Only present when dollars were actually measured as excluded. An
|
||||||
|
# empty_year fire can carry them too -- the year had no rows AND the
|
||||||
|
# component was suppressed -- which is strictly more informative.
|
||||||
|
if (isTRUE(s$suppressed_amount > 0)) {
|
||||||
|
bullet <- paste0(bullet, sprintf(
|
||||||
|
"\n $%s excluded from %s (%s), published as an aggregate or outside the crosswalk",
|
||||||
|
formatC(s$suppressed_amount, format = "f", digits = 0, big.mark = ","),
|
||||||
|
paste0("FY", s$suppressed_years, collapse = ", "),
|
||||||
|
paste(s$suppressed_codes, collapse = ", ")))
|
||||||
|
}
|
||||||
if (!is.null(s$ig_recipe_id)) {
|
if (!is.null(s$ig_recipe_id)) {
|
||||||
bullet <- paste0(bullet, sprintf(
|
bullet <- paste0(bullet, sprintf(
|
||||||
"\n intergovernmental counterpart: recipe = '%s'", s$ig_recipe_id))
|
"\n intergovernmental counterpart: recipe = '%s'", s$ig_recipe_id))
|
||||||
@@ -370,7 +383,7 @@
|
|||||||
bullet
|
bullet
|
||||||
}, character(1))
|
}, character(1))
|
||||||
cli::cli_inform(c(
|
cli::cli_inform(c(
|
||||||
i = "Coverage gap detected for the requested years; a harmonization recipe may fill it:",
|
i = "Incomplete coverage for the requested years; a harmonization recipe may fill it:",
|
||||||
stats::setNames(bullets, rep("*", length(bullets)))
|
stats::setNames(bullets, rep("*", length(bullets)))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,3 +378,29 @@ test_that("uscogdata#9: leaf-and-classified wide-era families never fire", {
|
|||||||
AND v.year = l.year AND v.item_code = l.item_code)")$n
|
AND v.year = l.year AND v.item_code = l.item_code)")$n
|
||||||
expect_equal(as.integer(n), 0L)
|
expect_equal(as.integer(n), 0L)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test_that("uscogdata#9: the cli message reports the suppressed dollars", {
|
||||||
|
skip_if_no_corpus()
|
||||||
|
expect_message(
|
||||||
|
cog_spending("061037123085", years = 2011L, category = "Public Welfare"),
|
||||||
|
"1,803,872,000", fixed = TRUE)
|
||||||
|
expect_message(
|
||||||
|
cog_spending("061037123085", years = 2011L, category = "Public Welfare"),
|
||||||
|
"FY2011", fixed = TRUE)
|
||||||
|
expect_message(
|
||||||
|
cog_spending("061037123085", years = 2011L, category = "Public Welfare"),
|
||||||
|
"E67", fixed = TRUE)
|
||||||
|
})
|
||||||
|
|
||||||
|
test_that("uscogdata#9: cog_explain() reports the suppressed dollars", {
|
||||||
|
# cog_explain()'s whole "print" output -- including the Suggestions
|
||||||
|
# section built from cli::cli_ul() -- is emitted on the message stream
|
||||||
|
# (verified empirically 2026-08-04: capture.output(..., type = "output")
|
||||||
|
# returns character(0) for this call; testthat::capture_messages() is what
|
||||||
|
# actually carries it), so that is the stream this test captures.
|
||||||
|
skip_if_no_corpus()
|
||||||
|
r <- suppressMessages(
|
||||||
|
cog_spending("061037123085", years = 2011L, category = "Public Welfare"))
|
||||||
|
out <- paste(testthat::capture_messages(cog_explain(r)), collapse = "")
|
||||||
|
expect_match(out, "271,589,000", fixed = TRUE)
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user