feat: cog_find_peers + cog_peer_compare

cog_find_peers selects peers from canonical_fips_xwalk by same-type,
same-state, and population-range (ratio or absolute) criteria,
ordered by |log(pop_ratio)| ascending.

cog_peer_compare accepts the find_peers result (or a plain character
vector of govids), pulls spending for target + peers via cog_spending,
and appends summary rows (summary_p25/p50/p75) so the whole result
can be faceted by `role` in a single ggplot call. Summary rows honor
per_capita + adjust_to_year by picking the right value column.
target_rank reports the target's rank among target+peers at max(years).

Provenance is rewritten with verb = cog_peer_compare and peer_count.

Also: globalVariables('.data') in zzz.R to silence R CMD check on
tidy-eval pronouns.

Tests: 21 new / 120 total pass. devtools::check() 0E/0W/2N.
This commit is contained in:
2026-04-24 11:17:46 -04:00
parent a6b53de2a7
commit cc4d21ec82
6 changed files with 381 additions and 0 deletions
+45
View File
@@ -0,0 +1,45 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/peers.R
\name{cog_find_peers}
\alias{cog_find_peers}
\title{Find peer governments by similarity criteria}
\usage{
cog_find_peers(
target_govid,
same_type = TRUE,
same_state = FALSE,
pop_range = c(0.7, 1.3),
is_ratio = TRUE,
pop_year = NULL,
max_peers = 10L
)
}
\arguments{
\item{target_govid}{Character scalar — `canonical_govid` of the target.}
\item{same_type}{If `TRUE` (default) restrict peers to the target's
`govs_type`.}
\item{same_state}{If `TRUE` restrict peers to the target's `fips_state`.
Default `FALSE`.}
\item{pop_range}{Length-2 numeric vector giving lower/upper bounds.}
\item{is_ratio}{If `TRUE` (default) `pop_range` is multiplied by the
target's `population_acs` to produce absolute bounds. If `FALSE`,
`pop_range` is interpreted as absolute population counts.}
\item{pop_year}{Reserved for future use (selecting ACS vintage). Currently
the corpus has a single snapshot so this argument has no effect.}
\item{max_peers}{Integer cap on the number of peers returned.}
}
\value{
Tibble with columns `canonical_govid`, `gov_name`, `fips_state`,
`population_acs`, `pop_ratio`, `rank`.
}
\description{
Selects peer governments from `canonical_fips_xwalk` by combinations of
government type, state, and population range. Peers are ordered by
`|log(pop_ratio)|` ascending (closest to the target's population first).
}
+44
View File
@@ -0,0 +1,44 @@
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/peers.R
\name{cog_peer_compare}
\alias{cog_peer_compare}
\title{Compare a target government against a peer set}
\usage{
cog_peer_compare(
target_govid,
peers,
category,
years,
per_capita = TRUE,
adjust_to_year = NULL
)
}
\arguments{
\item{target_govid}{Character scalar.}
\item{peers}{A tibble from [cog_find_peers()] or a character vector of
`canonical_govid`s.}
\item{category}{Character scalar or vector.}
\item{years}{Integer vector.}
\item{per_capita}{Default `TRUE` — peer compare usually normalizes by
population.}
\item{adjust_to_year}{Integer base year for CPI-U conversion or `NULL`.}
}
\value{
Tibble matching [cog_spending()]'s columns, plus a `role`
column taking values `"target"`, `"peer"`, `"summary_p25"`,
`"summary_p50"`, or `"summary_p75"`, and `target_rank` (target's rank
among target+peers at `max(years)`, NA for other rows). Provenance
attribute reports `verb = "cog_peer_compare"` and `peer_count`.
}
\description{
Pulls spending for the target plus a peer set (either a
[cog_find_peers()] result or a character vector of `canonical_govid`) and
appends peer-distribution summary rows (`summary_p25`, `summary_p50`,
`summary_p75`) so the result can be faceted by `role` in a single ggplot
call.
}