Closes the last blocked test in the suite. Owner ruled both halves of the open question yes on 2026-07-30. `cog_revenue()` gains `revenue_concept`, mirroring `expenditure_concept`, with Census's two published concepts defined as crosswalk `revenue_subtype` sets rather than item-code prefixes: general = own_source + federal + state + local_aid (the default) total = general + utility + liquor_store + insurance_trust The manual defines the first by subtracting the other three from the second (4.3), so both are computable only once all four families are named -- which cog_pipeline#79 does. Insurance trust now includes the employee-retirement X codes (X01/X02/X05/X08) alongside the Y codes. - inst/sql: revenue_long / revenue_long_harmonized carry EVERY revenue subtype; the concept narrows in R via the existing subtype_scope machinery, exactly as expenditure_concept narrows spending_long. - cog_explain() now prints each verb's OWN concept. It previously printed `expenditure_concept` unconditionally, so a cog_revenue() caller was told "Concept: primary" -- a spending concept their result has nothing to do with. - Fixture regenerated at pipeline_commit aadb46b (330 crosswalk rows). Corrected two stale expectations in the blocked test while un-skipping it. It asserted X01+X04+X05+X08 and omitted X02, which applies to state governments and is nonzero for Wisconsin; X04 is an exhibit code for an INTRAgovernmental transfer that Census's own "Total Emp Ret Rev" excludes. Verified against that Census field: the right set is X01+X02+X05+X08 = $2,283,883k, exactly. And its expected `total` of $33,377,093k predated the Y codes being classified -- complete Total Revenue for WI FY2012 is $34,881,961k (general 31,338,293 + Y 1,259,785 + X 2,283,883). Behaviour change worth knowing: `general` is now STRICT Census General Revenue, so utility and liquor store revenue leave the default. Measured on the fixture that is 15.9% of what cog_revenue() returned for cities, vs 1.2% for states and 1.7% for counties. Suite: 716 pass / 0 fail / 0 skip -- the first time this package has had no skipped tests. Closes #12
68 lines
3.2 KiB
R
68 lines
3.2 KiB
R
# R/revenue.R
|
|
|
|
#' Summarized revenue by category
|
|
#'
|
|
#' Mirror of [cog_spending()] for revenue categories. One row per
|
|
#' `(year, canonical_govid, revenue_subtype, category)`. Amounts are returned
|
|
#' in **full U.S. dollars** (raw Census values are in $1,000s; this verb
|
|
#' multiplies by 1000 and records the conversion in `provenance`).
|
|
#'
|
|
#' @inheritParams cog_spending
|
|
#' @param revenue_concept Which of Census's two published revenue concepts to
|
|
#' return. Concepts are defined as sets of the crosswalk's `revenue_subtype`
|
|
#' values -- never as item-code first letters, which cannot classify
|
|
#' correctly (prefix `Y` spans revenue, expenditure and balance codes, and
|
|
#' prefix `X` does the same):
|
|
#'
|
|
#' * `"general"` (default) -- Census General Revenue: `own_source` +
|
|
#' `federal` + `state` + `local_aid`. The manual defines this concept by
|
|
#' subtraction (section 4.3: *"General revenue comprises all revenue
|
|
#' except that classified as liquor store, utility, or insurance trust
|
|
#' revenue"*), so utility (`A91`-`A94`), liquor store (`A90`) and
|
|
#' insurance trust revenue are all excluded.
|
|
#' * `"total"` -- Census Total Revenue: every revenue subtype, i.e.
|
|
#' `general` plus utility, liquor store, and insurance trust revenue
|
|
#' (`Y01`/`Y02`/`Y04`/`Y11`/`Y12`/`Y51`/`Y52` and the employee-retirement
|
|
#' `X01`/`X02`/`X05`/`X08`).
|
|
#'
|
|
#' The two are related by Census's own identity, `Total Revenue = General +
|
|
#' Utility + Liquor Store + Insurance Trust`.
|
|
#'
|
|
#' Note that the employee-retirement (`X`) codes stop at FY2016, when those
|
|
#' systems moved out of the annual finance file into the separate Annual
|
|
#' Survey of Public Pensions, so a `"total"` series steps down at the
|
|
#' FY2016/FY2017 seam for reasons that are about collection scope rather
|
|
#' than revenue (series breaks `SB197`-`SB202`).
|
|
#' @return Tibble with columns `year`, `canonical_govid`, `gov_name`,
|
|
#' `revenue_subtype`, `category`, `amt_nominal`, optional `amt_real`,
|
|
#' optional `amt_per_capita_nominal`, optional `amt_per_capita_real`,
|
|
#' optional `pop_source`, `codes_included`, `aggregate_fallback`, `notes`,
|
|
#' and `value_source` when `complete = TRUE`.
|
|
#' @export
|
|
cog_revenue <- function(govid, years, category = NULL,
|
|
per_capita = FALSE, adjust_to_year = NULL,
|
|
basis = c("harmonized", "raw"), recipe = NULL,
|
|
revenue_concept = c("general", "total"),
|
|
complete = FALSE) {
|
|
# flow_prefixes no longer classifies rows (crosswalk revenue_subtype
|
|
# membership does -- General Revenue, i.e. everything except
|
|
# insurance_trust) -- it only scopes the recipe-suggestion machinery to
|
|
# this verb's recipe families (see R/suggestions.R).
|
|
.verb_spendrev(
|
|
verb = "cog_revenue",
|
|
view_base = "revenue_annotated",
|
|
subtype_col = "revenue_subtype",
|
|
flow_prefixes = c("T", "A", "U", "B", "C", "D"),
|
|
call = match.call(),
|
|
govid = govid,
|
|
years = years,
|
|
category = category,
|
|
per_capita = per_capita,
|
|
adjust_to_year = adjust_to_year,
|
|
basis = basis,
|
|
recipe = recipe,
|
|
revenue_concept = revenue_concept,
|
|
complete = complete
|
|
)
|
|
}
|