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
123 lines
5.6 KiB
R
123 lines
5.6 KiB
R
% Generated by roxygen2: do not edit by hand
|
|
% Please edit documentation in R/revenue.R
|
|
\name{cog_revenue}
|
|
\alias{cog_revenue}
|
|
\title{Summarized revenue by category}
|
|
\usage{
|
|
cog_revenue(
|
|
govid,
|
|
years,
|
|
category = NULL,
|
|
per_capita = FALSE,
|
|
adjust_to_year = NULL,
|
|
basis = c("harmonized", "raw"),
|
|
recipe = NULL,
|
|
revenue_concept = c("general", "total"),
|
|
complete = FALSE
|
|
)
|
|
}
|
|
\arguments{
|
|
\item{govid}{Character vector of `canonical_govid` values.}
|
|
|
|
\item{years}{Integer vector of years.}
|
|
|
|
\item{category}{Character vector of category names (from
|
|
`summary_categories.category`), or `NULL` for all categories.}
|
|
|
|
\item{per_capita}{If `TRUE`, adds `amt_per_capita_nominal` (and
|
|
`amt_per_capita_real` when `adjust_to_year` is set) using the per-year
|
|
Census F-33 population from `gov_population_yearly`. Result also gains
|
|
a `pop_source` column with values `"census_f33"` or `"unavailable"`
|
|
(the latter for gov types 4/5 and any row whose population is missing
|
|
in that year).}
|
|
|
|
\item{adjust_to_year}{Integer base year for CPI-U real-dollar conversion,
|
|
or `NULL` for nominal only.}
|
|
|
|
\item{basis}{`"harmonized"` (default) sums item codes through the
|
|
cross-vintage harmonization mapping (folding series-break-affected
|
|
codes onto a comparable target and excluding aggregate / discontinued
|
|
rows -- see the `harmonization` block in `cog_explain()`); `"raw"`
|
|
reproduces the pre-Phase-R2 behavior (published item codes, no
|
|
folding). On a corpus with `schema_version < 5` (no harmonization
|
|
tables), `basis` silently resolves to `"raw"` when left at its default
|
|
and the resolution is recorded in the provenance; explicitly passing
|
|
`basis = "harmonized"` on such a corpus aborts. Ignored when `recipe`
|
|
is set (see below).}
|
|
|
|
\item{recipe}{Optional harmonization recipe id (see [cog_recipes()]) for
|
|
multi-code cross-vintage series that a 1:1 harmonized_code mapping
|
|
can't express (e.g. a wide-era aggregate that only splits into leaf
|
|
codes in the modern era). Mutually exclusive with `category`. The
|
|
result's subtype column reads `"recipe"` and `category` reads the
|
|
recipe's label. Requires `schema_version >= 5`. A recipe query bypasses
|
|
`basis` entirely (it joins `long` directly rather than going through
|
|
the `*_annotated`/`*_annotated_harmonized` views), so the `basis`
|
|
argument is ignored and the result's provenance reports
|
|
`basis = "recipe"` with an inert `harmonization` block (`applied =
|
|
FALSE`, pointing at the `recipe` block instead) rather than a
|
|
possibly-misleading `"harmonized"`/`"raw"` value.}
|
|
|
|
\item{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`).}
|
|
|
|
\item{complete}{If `TRUE`, fill the requested grid so that a cell the
|
|
corpus does not carry still appears, labelled with **why** it is
|
|
missing, and add a `value_source` column to every row:
|
|
|
|
* `"reported"` — the corpus carries this cell.
|
|
* `"census_zero"` — dense-source year (`<= FY2011`), cell absent:
|
|
Census published `$0`. `amt_nominal` is `0`.
|
|
* `"not_reported"` — sparse-source year (`>= FY2012`), cell absent: the
|
|
government did not report, and the value is unknown. `amt_nominal` is
|
|
`NA`, **not** `0` — writing a zero there would invent data.
|
|
|
|
The grid comes from the corpus's `code_set` table, scoped to each
|
|
government's own type, so a county is never filled with cells only a
|
|
state can report. Reported rows are passed through untouched.
|
|
|
|
Defaults to `FALSE` (the historical behaviour: absent cells simply do
|
|
not appear). Needs a corpus published from 2026-07-29 onward, which is
|
|
when `representation`/`code_set` began shipping; aborts with class
|
|
`uscogdata_representation_unavailable` otherwise. Not available with
|
|
`recipe` or with `expenditure_concept = "total"` (class
|
|
`uscogdata_complete_unsupported`) — neither draws its cells from
|
|
`code_set`.}
|
|
}
|
|
\value{
|
|
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`.
|
|
}
|
|
\description{
|
|
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`).
|
|
}
|