Package 'fbiCDE'

Title: R Wrapper for the FBI Crime Data Explorer (CDE) API
Description: An R wrapper for the FBI Crime Data Explorer (CDE) API (<https://cde.ucr.cjis.gov/LATEST/>) providing access to UCR and NIBRS crime data. Functions cover lookups (agencies, offense codes, states), summarized crime data, arrest statistics, NIBRS incident-level data, Supplemental Homicide Reports (SHR), and police employment statistics. No API key is required for the current CDE host. Based on the original fbi package by Jacob Kaplan (https://github.com/jacobkap/fbi).
Authors: Jared E. Knowles [aut, cre]
Maintainer: Jared E. Knowles <[email protected]>
License: MIT + file LICENSE
Version: 0.2.0
Built: 2026-10-15 21:27:00 UTC
Source: https://github.com/civilytics/fbi_cde

Help Index


Add spatially-attributed embedded agencies to a place membership frame

Description

Attributes campus and other special-district agencies (any agency of type "University or College", "Other", or "Other State Agency" — CDE has no literal "transit" or "airport" type) to a place by point-in-polygon of their headquarters coordinates against Census place boundaries. Appends them to a place_agencies() result.

Usage

add_place_spatial_members(x, vintage = NULL, places_fun = NULL)

Arguments

x

A data.frame as returned by place_agencies().

vintage

Optional Census boundary year passed to tigris::places(). Boundaries change with annexations and new incorporations, so pin this when reproducibility matters. NULL uses the tigris default.

places_fun

Function used to fetch place polygons, called as places_fun(state, vintage) and expected to return an sf frame with GEOID, NAME, and CLASSFP columns. Defaults to tigris::places(). Exposed for testing; you should not need to set it.

Details

This is opt-in and best-effort. It requires sf and tigris (both in ‘Suggests’) and downloads boundary shapefiles. Without them the function emits a message and returns its input unchanged.

Sheriffs and state police are never candidates: unlike a university police department — whose headquarters genuinely sits on its campus inside the city — a sheriff's HQ point carries no information about its jurisdiction. That restriction is what makes point-in-polygon defensible for this tier.

Agencies with no coordinates in the bundled table cannot be placed: 271 of the 2,324 embedded-tier agencies (11.7%) have none and can never be spatially attributed by this function.

Value

x with spatially-attributed rows appended. On those rows place_type is "incorporated" or "cdp" (Census Designated Place, i.e. unincorporated) and place_fips is the GEOID of the polygon the agency's headquarters falls in: best-effort enrichment, unlike the place_fips of the place's own agency, which is the promised key described in place_agencies(). cousub_fips is NA on appended rows. The rows of x keep their codes. Appended rows carry attribution = "point_in_polygon". Their agency_class decides whether get_place_crime_detail() queries them by default: "campus" rows yes; "special" and "state" rows only when requested.

See Also

place_agencies()

Examples

## Not run: 
x <- place_agencies("Berkeley", "CA")
add_place_spatial_members(x)

## End(Not run)

The OMB delineation vintage the bundled CBSA crosswalk was built from

Description

CBSA definitions are revised periodically and counties move between metros, so results are only reproducible against a stated vintage. Sourced from the shipped data's own "vintage" attribute (stamped in data-raw/cbsa_crosswalk.R), not duplicated as an independent literal, so a rebuild that bumps the vintage cannot leave this constant stale. The 2023L below is a fallback for the (very unlikely) case where cbsa_crosswalk carries no "vintage" attribute; .onLoad() in R/fips.R overwrites it from the data as soon as the namespace is available – sysdata.rda is not guaranteed to be loaded yet while this file's top-level code is parsed, so the real read cannot happen here directly.

Usage

CBSA_VINTAGE

Format

An integer scalar.


Get the FBI CDE API base URL

Description

Returns the base URL for the FBI Crime Data Explorer API. Can be overridden via getOption("fbiCDE.cde.base_url") or Sys.getenv("FBI_CDE_BASE_URL") (for tests).

Usage

cde_base_url()

Value

A character string with the base URL.

Examples

cde_base_url()

Build an FBI CDE API path string

Description

Constructs the path portion of a CDE API endpoint URL from its components.

Usage

cde_path(type, level, offense = NULL)

Arguments

type

Character string with the endpoint type (e.g. "summarized", "arrest", "nibrs", "shr", "pe").

level

Character string with the geographic level. One of "national", "state/XX" (replace XX with state abbreviation), or "agency/XX" (replace XX with ORI code).

offense

Optional character string with the offense identifier (e.g. "V" for violent crime, "LAR" for larceny). Defaults to NULL.

Value

A character string with the API path, e.g. "summarized/national/V" or "shr/state/CA".

Examples

cde_path("summarized", "national", "V")
cde_path("summarized", "state/CA", "V")
cde_path("shr", "agency/CA0010900")

Build query parameters for FBI CDE API requests

Description

Formats year values and assembles a named list of query parameters for CDE API endpoint calls.

Usage

cde_query(from, to, type = NULL, four_digit_year = FALSE)

Arguments

from

Character string or numeric with the start date/year. When four_digit_year = FALSE expects "MM-YYYY" format; when TRUE accepts "YYYY" or a 4-digit numeric.

to

Character string or numeric with the end date/year. Same format rules as from.

type

Optional character string with the query type (e.g. "counts", "rates", "totals"). Defaults to NULL.

four_digit_year

Logical; when TRUE formats years as 4-digit YYYY (used for police employment pe endpoints). When FALSE (default) formats as MM-YYYY.

Value

A named list of query parameters, e.g. list(from = "01-2015", to = "12-2020", type = "counts").

Examples

cde_query("01-2015", "12-2020", type = "counts")
cde_query(2015, 2020, four_digit_year = TRUE)

List the law-enforcement agencies attributed to a county

Description

Returns every agency in the bundled agency table whose county and state match, classified by agency_class. This is an attribution model, not a spatial one: it reports the agencies attributed to a county, not crime known to have occurred there. It returns every class; the crime functions (get_county_crime_detail(), get_metro_crime_detail()) then choose which classes to query.

Usage

county_agencies(county, state)

Arguments

county

County name (case-insensitive; e.g. "Alameda").

state

Two-letter state abbreviation (e.g. "CA").

Value

A data.frame with columns ori, agency_name, agency_type_name, agency_class, county_name, state_abbr, county_fips, latitude, longitude, agency_county_names. county_name and county_fips (5-digit, character, preserving leading zeros) identify the queried county on every row. agency_county_names is the CDE's own county list for the agency: semicolon-separated for an agency that polices several counties (e.g. Columbus PD, "DELAWARE; FAIRFIELD; FRANKLIN"). Such an agency is attributed in full to each of its counties, so summing results across counties counts it more than once. agency_class is one of "county_primary" (sheriff, parish), "municipal" (city police), "campus", "state" (state police and other state agencies), "special" (transit, school, airport, port, park and railroad police, task forces) or "tribal". Returns a zero-row frame (with a warning) if no agencies match.

Agencies the CDE leaves without a county

The CDE assigns no county to three agencies that each police a whole county or county-equivalent, so the package attributes them itself, by ORI:

  • New York City Police Department (NY0303000): the five boroughs, Bronx, Kings, New York, Queens and Richmond counties.

  • Metropolitan Police Department of the District of Columbia (DCMPD0000): the District of Columbia.

  • Baltimore City Sheriff's Office (MD0040600): Baltimore city.

Connecticut agencies are also attributed to their planning region, the county equivalent Connecticut adopted in 2022 and the unit its metro areas are built from, as the CDE's live agency directory reports it. Query either a traditional county (county_agencies("Hartford", "CT")) or a region (county_agencies("Capitol Planning Region", "CT")), but do not add the two systems together: every agency is in one of each. Six agencies have no region in the directory (the state police, the DMV, two tribal agencies, and Yale and UConn Health, which it lists under other identifiers).

The NYPD reports one series for the whole city; the CDE has no borough breakdown. Like any multi-county agency it is attributed in full to each of its counties, so county_agencies("Kings", "NY") includes the NYPD, and the crime functions return citywide NYPD figures for Brooklyn, with New York City's population. A borough's results therefore describe the city, not the borough. Use the New York metro, or the NYPD itself, rather than summing boroughs. For these agencies agency_county_names holds the package's attribution, not a list from the CDE.

Examples

## Not run: 
county_agencies("Alameda", "CA")

## End(Not run)

County FIPS Code Lookup

Description

Map a state + county name to a 5-digit county FIPS code using the FBI's internal agency-to-county mapping and a tigris-derived crosswalk.

Usage

county_to_fips(state, county)

counties_with_fips()

Arguments

state

A two-letter state abbreviation (e.g. "CA", "TX") or a two-digit state FIPS code (e.g. "06", "48"). Case-insensitive.

county

A county name as stored in fbi_api_agencies (typically uppercase, may include " CITY" suffix for independent cities, or ";" for multi-county agencies).

Details

The crosswalk is built at package build time from tigris::counties() and covers 98.6% of unique (state, county) pairs in fbi_api_agencies.

Unresolvable cases:

  • county = "N/A" (agency has no county assigned — state police, tribal, etc.)

  • VALDEZ-CORDOVA (dissolved AK borough; split into Chugach & Copper River census areas in 2015, no single FIPS exists)

Value

A character string with the 5-digit county FIPS code (e.g. "06037") or NA_character_ when the county cannot be resolved (e.g. "N/A" county, dissolved boroughs). counties_with_fips() returns a data.frame with one row per resolvable county: state_abbr, county_name (as the CDE spells it), and county_fips.

Examples

county_to_fips("CA", "LOS ANGELES")
#> "06037"

county_to_fips("TX", "DEWITT")
#> "48123"

county_to_fips("MD", "BALTIMORE CITY")
#> "24510"

county_to_fips("MO", "ST LOUIS CITY")
#> "29510"

county_to_fips("AK", "N/A")
#> NA

All agencies included in the FBI's Crime Data Explorer API.

Description

A dataset containing information about the 18,459 agencies included in the FBI's API. It is a snapshot: NIBRS start dates run to September 2019, so the NIBRS columns predate the large 2020-2021 transition. Use get_agency_participation() for an agency's current NIBRS status.

Usage

fbi_api_agencies

Format

A data frame with 18459 rows and 13 variables:

ori

9-character unique ID for the agency (ORI)

agency_name

Agency name

agency_type_name

Type of department, e.g. City, County, University or College. Louisiana's and Alaska's types are the CDE's live directory's: the snapshot had typed every Louisiana agency "Parish" and every Alaska agency by its borough or census area. NA for 18 of those agencies that the directory no longer lists

state_name

State name

state_abbr

State abbreviation

division_name

Census division name

region_name

Census region name

region_desc

Census region code

county_name

County name, uppercase. Semicolon-separated for an agency that polices several counties; "N/A" when the agency has no county. This is the CDE's own value: the geography functions also attribute three "N/A" agencies (the NYPD, DC's Metropolitan Police and the Baltimore City Sheriff) to their counties, which this table does not show; see county_agencies

nibrs

Logical: whether the agency reported to NIBRS as of the snapshot

latitude

Numeric agency latitude; NA when unknown

longitude

Numeric agency longitude; NA when unknown

nibrs_start_date

Date the agency started reporting to NIBRS; NA if it had not

Source

https://cde.ucr.cjis.gov/LATEST/


Flatten CDE JSON response

Description

Turns an object-of-label -> period -> value into a long/tidy data.frame

Usage

flatten_cde_json(obj)

Arguments

obj

A nested list/object from the CDE API with structure label -> period -> value

Value

A data.frame with columns: label, period, value

Examples

obj <- list(
  "United States Offenses" = list(
    "01-2015" = 27.6,
    "01-2016" = 29.62
  )
)
## Not run: 
flatten_cde_json(obj)

## End(Not run)

Get all agencies from the CDE API

Description

Iterates over every state in get_states() and fetches its agency directory from the CDE endpoint agency/byStateAbbr/{state} (the same endpoint the participation functions use) to rebuild the full agency table. This issues one request per state.

Usage

get_agencies()

Value

A data.frame with one row per agency and one column per field the API returns (currently ori, counties, is_nibrs, latitude, longitude, state_abbr, state_name, agency_name, agency_type_name, nibrs_start_date), all stored as character and sorted by ori. These field names follow the live API and differ from the bundled fbi_api_agencies snapshot (e.g. counties rather than county_name). States whose request fails are skipped with a warning and listed in attr(x, "failed_states").

Examples

## Not run: 
agencies <- get_agencies()
head(agencies)

## End(Not run)

Get agency-level crime data from the UCR Offenses Known and Clearances

Description

Get agency-level crime data from the UCR Offenses Known and Clearances

Usage

get_agency_crime(
  ori,
  from = "01-2015",
  to = "12-2020",
  offense = "V",
  comparison = FALSE
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

Offense code (default "V" for violent crime). See get_offense_codes() for available codes.

comparison

If TRUE, also return the comparison series the API sends alongside the agency's own: its state's and the nation's rates (these have no count). Default FALSE returns only the agency's own series.

Value

A data.frame with columns geography, offense (the requested code), measure ("offenses" or "clearances"), period, count, rate (per 100,000 population, for that month), population (the population the series covers) and participated_population (the population of the agencies that reported that month). Their ratio is the reporting coverage: a state or national count below full coverage is the sum of the agencies that reported, not an estimate for everyone. With comparison = TRUE, two more columns follow geography: series ("agency", "state" or "national") and series_name (e.g. "Oakland Police Department", "California", "United States").

See Also

Other UCR crime functions: get_agency_participation(), get_leoka(), get_leoka_monthly(), get_region_participation(), get_reported_arson(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_agency_crime("AK0010100")

# The agency alongside its state and the nation
get_agency_crime("CA0010900", from = "01-2019", to = "03-2019",
                 comparison = TRUE)

## End(Not run)

Get information about the selected agency

Description

Get information about the selected agency including the 9-digit ORI, geographic information, type of agency, and whether they report to NIBRS.

Usage

get_agency_info(agency, state = NULL, ori_only = FALSE, exact_match = TRUE)

Arguments

agency

A string or vector of strings with the name of the agency you want to lookup (capitalized is ignored).

state

A string or vector of strings of state names. If used, returns only agencies in that state. This is useful in cases where multiple agencies have the same name in different states and you only want specific states.

ori_only

If TRUE (not default), returns only the ORI and the agency_name columns.

exact_match

If TRUE (default), finds matches based on exact match of agency name. Else, treats each element of agency as a regular expression (case ignored) and returns the agencies whose names match any of them.

Value

A data.frame with information about the agency - including ORI code and geographic information. The agency will have as many rows as agencies matched from the agency input.

Examples

get_agency_info("Oakland Police Department")
get_agency_info("Oakland Police Department", state = "california")

Get agency-level NIBRS participation status

Description

The current CDE API has no dedicated participation-rate endpoint: the legacy participation/... paths this function used to call return 404, and the ⁠participation/*⁠ namespace still present in the current API is scoped to Use-of-Force agency reporting, not general UCR/NIBRS participation (confirmed by inspecting the CDE web app's client bundle and probing the live API – see Issue #1). This is a modernized reimplementation: it reports whether ori currently reports to NIBRS, sourced live from ⁠agency/byStateAbbr/⁠ (state derived from the first two characters of ori; Nebraska's NB and Guam's GM are looked up as NE and GU), in place of the retired year-by-year SRS/NIBRS participation series.

Usage

get_agency_participation(ori, key = get_api_key())

Arguments

ori

A string of the 9-character ORI code for the desired agency.

key

API key for the legacy FBI API (not needed for CDE API).

Value

A one-row data.frame with columns: ori, agency_name, agency_type_name, state_abbr, state_name, county, is_nibrs, nibrs_start_date.

Author(s)

Jared E. Knowles, Civilytics Consulting

See Also

Other UCR crime functions: get_agency_crime(), get_leoka(), get_leoka_monthly(), get_region_participation(), get_reported_arson(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_agency_participation("CA0010900")

## End(Not run)

Returns the FBI's Crime Data Explorer API key

Description

Deprecated. The current CDE API (⁠cde.ucr.cjis.gov/LATEST/⁠) does not require an API key. This function is retained only for backward compatibility with code that previously used the legacy api.data.gov-hosted API.

Usage

get_api_key()

Value

NULL. A deprecation message is printed on every call.

Examples

## Not run: 
get_api_key()

## End(Not run)

Get arrest offense counts from the UCR Crime Data Explorer

Description

Retrieves monthly arrest counts for an agency, a state, or the nation, for all offenses or one, from the CDE API endpoint ⁠arrest/<level>/<code>⁠ with type=counts.

Usage

get_arrest_count(
  ori = NULL,
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "all",
  comparison = FALSE
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

"all" (the default) for total arrests, or one offense. An offense is a name from any of the API's three levels, matched case-insensitively: offense names ("Robbery", "Drug Possession"), categories ("Drug/Narcotic Offenses") and breakdowns ("Drug Possession - Marijuana"); see list_ucr_arrest_offenses(). The API addresses offenses by numeric code (ucr_arrest_offense_codes), one per breakdown, so a name covering several (a category such as "Drug/Narcotic Offenses" has 11) costs one request per code, and the series is their sum. A string that is a name at more than one level resolves as an offense name first: "Sex Offenses" is code 240, not the category of that name, which holds only "Rape (Legacy)". Note that "Drug Abuse Violations" is only the drug arrests not classed as possession or sale; total drug arrests are "Drug/Narcotic Offenses".

comparison

If TRUE, also return the comparison series the API sends alongside an agency's or state's own: its state's and the nation's arrest rates (these have no count). Default FALSE returns only the queried geography's own series.

Value

A data.frame with one row per month: geography, offense ("all", or the API's spelling of the offense name), measure ("arrests"), period, count, rate (per 100,000 population, for that month), and the population and participated_population described in get_agency_crime() (their ratio is the reporting coverage). With comparison = TRUE, series and series_name columns follow geography, as in get_agency_crime().

See Also

Other UCR arrest functions: get_arrest_demographics(), get_arrest_demographics_all(), list_ucr_arrest_offenses()

Examples

## Not run: 
get_arrest_count(ori = "CA0010900")
get_arrest_count(state_abb = "CA")
get_arrest_count()
get_arrest_count(state_abb = "CA", offense = "Robbery")
get_arrest_count(state_abb = "CA", offense = "Drug/Narcotic Offenses")

## End(Not run)

Get arrestee demographics from the UCR Crime Data Explorer

Description

Retrieves arrest counts broken down by demographic categories (sex, age by sex, race) over the date range, for all offenses or one. Uses the CDE API endpoint ⁠arrest/<level>/<code>⁠ with type=totals. With an offense this is the offense-by-age cross-tabulation: juvenile arrests for larceny, say.

Usage

get_arrest_demographics(
  ori = NULL,
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "all"
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

"all" (the default), or one offense, as in get_arrest_count(). A name covering several codes is the sum of their demographics.

Value

A data.frame with columns: geography, offense, period, demographic_type, demographic_value, count

All-offense demographics are incomplete

The API's all-offense demographics leave out arrests filed under the five "(Unspecified)" offense codes (140, 150, 151, 156 and 170, e.g. "Drug Abuse Violations (Unspecified)"), although its all-offense counts include them: in Ohio in 2023, 883 of 188,836 arrests, 57 of them juvenile. Summing get_arrest_demographics() over the offense names includes them.

See Also

Other UCR arrest functions: get_arrest_count(), get_arrest_demographics_all(), list_ucr_arrest_offenses()

Examples

## Not run: 
get_arrest_demographics(ori = "CA0010900")
get_arrest_demographics(state_abb = "CA")
get_arrest_demographics(state_abb = "OH", offense = "Larceny")

## End(Not run)

Get arrestee demographics (all offenses)

Description

Deprecated. Use get_arrest_demographics(), which takes an offense. This alias returns all-offense demographics (offense = "all") and emits a warning. It is retained for backward compatibility and may be removed in a future release.

Usage

get_arrest_demographics_all(...)

Arguments

...

Arguments passed to get_arrest_demographics() (e.g. ori, state_abb, from, to). Any offense argument is ignored.

Value

A data.frame with columns: geography, offense, period, demographic_type, demographic_value, count

See Also

Other UCR arrest functions: get_arrest_count(), get_arrest_demographics(), list_ucr_arrest_offenses()

Examples

## Not run: 
get_arrest_demographics_all(state_abb = "CA")

## End(Not run)

Crime reported by a county's own primary agency (sheriff/parish)

Description

Resolves the single county_primary ORI for a county and returns its own get_agency_crime() series. This disambiguates "the county sheriff's own reported crime" from "crime aggregated across the county" (get_county_crime_detail()).

Usage

get_county_agency_crime(
  county,
  state,
  offense = "V",
  from = "01-2015",
  to = "12-2020",
  comparison = FALSE
)

Arguments

county

County name (case-insensitive).

state

Two-letter state abbreviation.

offense

Offense code (default "V"; see get_offense_codes()).

from, to

Date range in MM-YYYY format.

comparison

If TRUE, also return the comparison series the API sends alongside the agency's own: its state's and the nation's rates (these have no count). Default FALSE returns only the agency's own series.

Value

The get_agency_crime() data.frame for the county's primary agency.

Examples

## Not run: 
get_county_agency_crime("Alameda", "CA")

## End(Not run)

Aggregate county crime detail into a coverage-transparent rollup

Description

Sums itemized agency-level detail (from get_county_crime_detail()) into a single county-wide series. Unlike the FBI's published county rate, this function never emits a bare rate: every row carries the chosen denominator value, which denominator was used (denominator_type), and a coverage_fraction (participated / total population) so the user can see exactly how much of the county is covered by reporting agencies.

Usage

get_county_crime(detail, denominator = "jurisdiction_pop")

Arguments

detail

A data.frame as returned by get_county_crime_detail(), with at least the columns: county_name, state_abbr, offense, period, count, population, participated_population. Imputed counts (from impute_reporting_gaps()) are summed like reported ones.

denominator

Denominator strategy. One of:

  • "jurisdiction_pop" — sum of agency population columns (default; coherent with CDE population semantics).

  • "participated_pop" — sum of agency participated_population columns (coverage-consistent; the rate reflects only reporting coverage).

  • "census_pop" — use a single external population value per period. Requires detail to have a census_population column (e.g. from join_census_pop()).

Details

The default denominator ("jurisdiction_pop") sums each agency's own population column. Empirical probes confirm this is coherent: a sheriff's population is the unincorporated remainder it polices, and contract cities report under their own ORI — so the sum of jurisdiction_pop approximates the full county with no double-count between sheriff and cities. Use denominator = "participated_pop" for a coverage-consistent rate (drops uncovered months), or denominator = "census_pop" to supply an external Census population (requires the county_fips column from county_agencies() and a Census join).

One exception: an agency that polices several counties reports a single series, and it is counted in full in each of its counties, count and population alike. Columbus PD puts all of Columbus in Delaware and Fairfield counties' totals as well as Franklin's, and the NYPD makes every borough's total New York City's. Those rows are the ones whose agency_county_names lists more than one county; drop them from detail first to exclude such agencies.

A period in which no agency reported has an NA count and rate, not 0; coverage_fraction is then 0. Rows are in chronological order.

Value

A data.frame with columns: county_name, state_abbr, offense, period, count (sum of reported counts; NA when no agency reported), population (the denominator value used), participated_population (sum of participated populations), rate (count / population * 1e5), denominator_type (which strategy was used), and coverage_fraction (participated_population / population). Returns a zero-row frame with correct columns if detail is empty. If detail carries attr(detail, "dropped") (agencies whose request failed in get_county_crime_detail()), the result warns and keeps that attribute: those agencies are missing from every total, including the denominator.

See Also

vignette("estimates") for reported, estimated and imputed crime.

Examples

## Not run: 
detail <- get_county_crime_detail("Alameda", "CA",
                                  from = "01-2019", to = "12-2019")
get_county_crime(detail)

# Coverage-consistent rate instead of the full jurisdiction denominator.
get_county_crime(detail, denominator = "participated_pop")

## End(Not run)

Itemized crime detail for every agency attributed to a county

Description

Fans out one request per member agency and returns their crime series unsummed — one row per agency-period — with each agency's agency_class, coverage (population, participated_population, reported), and a per-agency rate (count / participated_population * 1e5). This is the transparent, power-user primitive; it applies no aggregation and takes no stance on denominators.

Usage

get_county_crime_detail(
  county,
  state,
  offense = "V",
  from = "01-2015",
  to = "12-2020",
  agency_class = NULL,
  include_statewide = FALSE,
  progress = FALSE
)

Arguments

county

County name (case-insensitive).

state

Two-letter state abbreviation.

offense

Offense code (default "V"; see get_offense_codes()).

from, to

Date range in MM-YYYY format.

agency_class

Optional character vector of classes to query instead of the default set ("county_primary", "municipal", "campus"): any of those plus "special", "state" and "tribal". See county_agencies() for what each class holds.

include_statewide

If TRUE, also query state agencies (state police and highway patrol, other state agencies). Many of their records are county or troop units, but some are headquarters records covering the whole state, attributed to the county they sit in, and agency type does not tell the two apart. Default FALSE.

progress

If TRUE, print a simple progress line per agency.

Details

By default it queries the agencies whose jurisdiction is a specific area below the state: the sheriff, city police and campus police. Add state agencies with include_statewide = TRUE. Special-purpose agencies (transit, school, airport, port, park and railroad police, task forces) and tribal agencies are queried only when named in agency_class: the first group mixes single-site agencies with multi-county task forces attributed to one county, and how tribal agencies should attribute to counties is unresolved.

An agency that polices several counties reports one series, which is returned in full for each of its counties: Columbus PD's rows are the same for Delaware, Fairfield and Franklin counties, OH. The extreme case is New York City, where the NYPD is the police of all five boroughs: any borough returns citywide NYPD counts with New York City's population. Do not sum counties that share an agency; see county_agencies(). Such rows are the ones whose agency_county_names lists more than one county.

Value

A data.frame with one row per agency-period: the agency metadata from county_agencies() (including county_fips, which join_census_pop() needs, and agency_county_names, the CDE's own county list), then offense, period, count, population, participated_population, rate, and reported. Agencies whose request or parse fails are dropped with a warning; their ORIs are recorded in attr(x, "dropped") and the errors in attr(x, "dropped_reasons").

Examples

## Not run: 
get_county_crime_detail("Alameda", "CA", from = "01-2019", to = "12-2019")

## End(Not run)

Get national LEOKA (Law Enforcement Officers Killed and Assaulted) totals

Description

Counts of law enforcement officers feloniously killed, nationally, by year. Despite the program's name, these are not assault counts: the totals match the FBI's published felonious-killing figures (46 officers in 2020, 73 in 2021).

National only: the live leoka/ytd endpoint ignores state/agency query parameters (verified against the live API – requests with and without state/ori params return identical data), so the current CDE API has no state- or agency-level LEOKA breakdown. Data is only available from 2020 onward; earlier years return an empty (0-row) result for that year and are dropped, since ⁠leoka/ytd?year=<2015-2019>⁠ returns a null payload on the live API.

Usage

get_leoka(from = 2020, to = 2024)

Arguments

from

Start year (4-digit), default 2020 (earliest year with data).

to

End year (4-digit), default 2024.

Value

A data.frame with one row per requested year with data and columns: year, month (always NA; year-to-date totals have no month), total_officers (officers feloniously killed), total_incidents (incidents in which they were killed), and the ⁠_dod⁠/⁠_doi⁠ splits of each. The API does not label those splits (they sum to the totals) and the package does not interpret them.

Author(s)

Jared E. Knowles, Civilytics Consulting

See Also

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka_monthly(), get_region_participation(), get_reported_arson(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_leoka(2020, 2024)

## End(Not run)

Get national LEOKA totals for a single month

Description

National only; see get_leoka().

Usage

get_leoka_monthly(year, month)

Arguments

year

4-digit year.

month

Month, 1-12.

Value

A one-row data.frame; see get_leoka() for columns.

Author(s)

Jared E. Knowles, Civilytics Consulting

See Also

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka(), get_region_participation(), get_reported_arson(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_leoka_monthly(2020, 1)

## End(Not run)

Itemized crime detail for every agency in a metropolitan area

Description

Fans out one request per member agency across the metro's counties and returns their crime series unsummed – one row per agency-period – with coverage columns and the CBSA metadata.

Usage

get_metro_crime_detail(
  metro,
  state = NULL,
  offense = "V",
  from = "01-2015",
  to = "12-2020",
  agency_class = NULL,
  include_statewide = FALSE,
  max_agencies = 150,
  progress = TRUE
)

Arguments

metro

A CBSA title (e.g. "Pittsburgh, PA"), or a short name ("Pittsburgh"). See list_metros() for the available values.

state

Optional two-letter state abbreviation, used only to disambiguate an ambiguous short name.

offense

Offense code (default "V"; see get_offense_codes()).

from, to

Date range in MM-YYYY format.

agency_class, include_statewide

Which agencies to query, as for get_county_crime_detail().

max_agencies

Refuse to run if the filtered agency set is larger than this (default 150), erroring before any request is issued. Set to Inf to disable, or narrow the set with agency_class.

progress

If TRUE (the default here, unlike the county and place equivalents), print a progress line per agency. At metro scale silence is indistinguishable from a hang.

Details

This can be an expensive call. A metro is the union of whole counties, so the largest are very large: New York-Newark-Jersey City resolves to roughly 489 agencies, Chicago 314. Every agency is one sequential request. The median CBSA is only 7 agencies, so the cost is highly skewed – which is why max_agencies refuses the large cases up front rather than letting them run silently for minutes.

No metro-level aggregate is provided. Summing across a metro raises the same denominator question the county aggregate deferred, and a metro's is harder (multi-state, mixed coverage).

Value

A data.frame with one row per agency-period. Agencies whose request or parse fails are dropped with a warning; their ORIs are recorded in attr(x, "dropped") and the errors in attr(x, "dropped_reasons").

See Also

metro_agencies(), list_metros(), get_county_crime_detail().

Examples

## Not run: 
# A small micropolitan area is cheap.
get_metro_crime_detail("Aberdeen, WA", from = "01-2019", to = "12-2019")

## End(Not run)

Get the FBI's published NIBRS estimates for a state or the nation

Description

Returns the FBI's estimate: its published figure for a state or the nation, which adds a statistical model's prediction for everything outside NIBRS to what agencies reported in NIBRS. Each value comes with its 95% confidence interval. Compare it with crime reported to the FBI using imputation_gap().

Usage

get_nibrs_estimate(state_abb = NULL, year, offense = "V", table = "Offense")

Arguments

state_abb

String for state abbreviation. If NULL (default) returns national data.

year

A single year, e.g. 2022.

offense

A summary offense code ("V", the default, for violent crime; "P", "ROB", "ASS", "BUR", "LAR", "MVT", "ARS", "HOM" or "RPE") or an id from nibrs_estimation_indicators.

table

Which of the estimate's tables to return: "Offense" (the default), "Victim", "Incident" or "Arrest".

Details

The API publishes these estimates for the years in nibrs_estimation_years (2021 and 2022), and only for states and the nation: nothing for counties, cities or metro areas. A year it does not cover fails with the API's own message listing the years it has. The estimates come from ⁠nibrs-estimation/⁠, the endpoint behind the CDE's "NIBRS Estimates" page, which the CDE's public API documentation does not list.

Value

A data.frame with one row per category: geography, year, offense, indicator (the estimates API's offense id), table, variable (e.g. "Victim age"), category (e.g. "25-34"), estimate, lower_bound and upper_bound. The offense total is the "Offense" table's row with variable "Offense Count - Total". Bounds are as published: NA where the FBI gives none, and below zero for some small counts. A geography the FBI publishes no estimate for (Arizona, in both years) returns zero rows.

See Also

vignette("estimates") for reported, estimated and imputed crime.

Other NIBRS functions: get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

## Not run: 
ca <- get_nibrs_estimate("CA", year = 2021)
ca[ca$variable == "Offense Count - Total", ]

## End(Not run)

Gets offender-level data from the FBI's National Incident-Based Reporting System (NIBRS)

Description

Retrieves offender counts by age, ethnicity, race or sex for one offense, summed over the date range, from the CDE API endpoint ⁠nibrs/<level>/<offense>⁠ with type=totals. Ages come in ten-year buckets ("10-19", ...).

Usage

get_nibrs_offender(
  ori = NULL,
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "V",
  variable = "race"
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

Offense code (default "V", violent crime): a summary group such as "V", "P", "ROB" or "BUR", or a NIBRS offense code such as "13B" or "35A". See list_nibrs_offenses(). Offense names such as "robbery" are rejected: the API returns no data for them.

variable

The variable to break offenders down by (default "race"). See list_nibrs_offender_variables().

Value

A data.frame with the columns described in get_nibrs_victim().

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

## Not run: 
get_nibrs_offender(state_abb = "OH", offense = "BUR", variable = "age",
                   from = "01-2023", to = "12-2023")

## End(Not run)

Gets offense-level data from the FBI's National Incident-Based Reporting System (NIBRS)

Description

Retrieves offense characteristics – the weapons involved, or the other offenses reported in the same incidents – for one offense, summed over the date range, from the CDE API endpoint ⁠nibrs/<level>/<offense>⁠ with type=totals.

Usage

get_nibrs_offense(
  ori = NULL,
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "V",
  variable = "weapons"
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

Offense code (default "V", violent crime): a summary group such as "V", "P", "ROB" or "BUR", or a NIBRS offense code such as "13B" or "35A". See list_nibrs_offenses(). Offense names such as "robbery" are rejected: the API returns no data for them.

variable

"weapons" (the default) or "related_offenses". See list_nibrs_offense_variables().

Value

A data.frame with the columns described in get_nibrs_victim().

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

## Not run: 
get_nibrs_offense(state_abb = "OH", offense = "ROB", variable = "weapons",
                  from = "01-2023", to = "12-2023")

## End(Not run)

Gets victim-level data from the FBI's National Incident-Based Reporting System (NIBRS)

Description

Retrieves victim counts by a demographic or situational variable (age, ethnicity, location, race, relationship, sex) for one offense, summed over the date range, from the CDE API endpoint ⁠nibrs/<level>/<offense>⁠ with type=totals.

Usage

get_nibrs_victim(
  ori = NULL,
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "V",
  variable = "race"
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

Offense code (default "V", violent crime): a summary group such as "V", "P", "ROB" or "BUR", or a NIBRS offense code such as "13B" or "35A". See list_nibrs_offenses(). Offense names such as "robbery" are rejected: the API returns no data for them.

variable

The variable to break victims down by (default "race"). See list_nibrs_victim_variables().

Details

An agency or state that did not report to NIBRS in the period returns zero rows, with a message.

Value

A data.frame with columns: geography, offense (the code), period, demographic_type (the variable), demographic_value, count.

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

## Not run: 
get_nibrs_victim(state_abb = "OH", offense = "ROB", variable = "age",
                 from = "01-2023", to = "12-2023")

## End(Not run)

Get offense codes from the CDE API

Description

Retrieves valid offense codes from the CDE lookup endpoint.

Usage

get_offense_codes(type = "crime-trend")

Arguments

type

Character string for the offense type (e.g. "crime-trend", "arrest", "hate-crime", "nibrs"). "nibrs" currently returns no codes live (crimeGroups: null).

Value

A data.frame with offense codes and labels.

Examples

## Not run: 
offenses <- get_offense_codes()
head(offenses)

## End(Not run)

Itemized crime detail for every agency attributed to a place

Description

Fans out one request per member agency and returns their crime series unsummed — one row per agency-period — carrying agency_class, coverage (population, participated_population, reported), a per-agency rate, and the attribution that earned each agency its membership.

Usage

get_place_crime_detail(
  place,
  state,
  county = NULL,
  offense = "V",
  from = "01-2015",
  to = "12-2020",
  agency_class = NULL,
  include_statewide = FALSE,
  agencies = NULL,
  progress = FALSE
)

Arguments

place

Place name (case-insensitive; e.g. "Lufkin"). Supply either the bare name or the full agency name — both resolve.

state

Two-letter state abbreviation (e.g. "TX").

county

Optional county name, needed only to disambiguate a place name that occurs in more than one county of the same state.

offense

Offense code (default "V"; see get_offense_codes()).

from, to

Date range in MM-YYYY format.

agency_class

Optional character vector of place classes to query instead of the default set ("place_primary", "campus"): any of those plus "special" and "state".

include_statewide

If TRUE, also query state agencies (class "state", e.g. a state park's rangers or a capitol police force) found inside the place by add_place_spatial_members(). Default FALSE.

agencies

Optional pre-resolved agency membership data.frame, e.g. the output of place_agencies() with add_place_spatial_members() applied. When supplied, it is used directly instead of calling place_agencies() internally — this is the only way to reach "campus", "special" or "state" rows, since place_agencies() alone never returns them. Campus rows supplied this way are queried by default. Must be a data.frame carrying at least ori, agency_name, agency_type_name, agency_class, place_name, county_name, state_abbr, and attribution. Missing place_type, place_fips and cousub_fips columns are filled from the place crosswalk by ORI.

Column presence is validated, but membership is not: a hand-built frame can contain any ORI, including a sheriff or state police agency. The supported path (place_agencies(), optionally through add_place_spatial_members()) can never produce one — county, parish, state-police, and tribal agencies are excluded structurally. If you build the frame yourself, that exclusion becomes yours to maintain: attributing a sheriff to a place double-counts against the place's own agency, because a sheriff polices the unincorporated remainder and contract cities report under their own city ORI.

progress

If TRUE, print a simple progress line per agency.

Details

In the common case a place has exactly one member agency, so this is a by-name wrapper over that agency's series. That is the value: ORI discovery is the package's primary friction, and this removes it.

No place-level aggregate is provided. Summing an opted-in campus agency into a city total is a modeling choice, not arithmetic; see the county Layer 2 (get_county_crime()) for the shape that decision takes.

Value

A data.frame with one row per agency-period, carrying: ori, agency_name, agency_type_name, agency_class, place_name, the Census codes place_type, place_fips and cousub_fips (see place_agencies()), county_name, state_abbr, attribution, offense, period, count, population, participated_population, rate, and reported. Agencies whose request or parse fails are dropped with a warning and recorded in attr(x, "dropped"). If filtering (via agency_class/include_statewide) empties a non-empty agency set, a warning names the place and the filter responsible, and a zero-row frame is returned.

See Also

place_agencies(), add_place_spatial_members(), impute_reporting_gaps() for filling reporting gaps in the result.

Examples

## Not run: 
get_place_crime_detail("Lufkin", "TX", from = "01-2019", to = "12-2019")

# Compose with add_place_spatial_members() to reach campus agencies, which
# are then queried by default alongside the city's own:
x <- add_place_spatial_members(place_agencies("Berkeley", "CA"))
get_place_crime_detail("Berkeley", "CA", agencies = x)

## End(Not run)

Get police staffing data

Description

Returns annual counts of sworn officers and civilian employees, by sex, for an agency, a state, or the nation, from the CDE's police employment (pe) endpoint.

Usage

get_police_employment(
  ori = NULL,
  state_abb = NULL,
  region = NULL,
  from = "2015",
  to = "2020"
)

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

region

Not supported: the CDE publishes no region-level police employment, and passing a region is an error. Sum the states instead.

from, to

First and last year, as four-digit YYYY strings (defaults "2015" and "2020"). Unlike the other data functions, police employment is annual.

Value

A data.frame with one row per year: year, male_officers, female_officers, male_civilians, female_civilians, ori (the requested geography), and the totals male_total, female_total, civilians_total, officers_total and employees_total, then participated_population (the population of the agencies that reported) and employees_per_1000 (employees per 1,000 of that population). For a state or the nation the counts are sums over the agencies that reported, so they move with coverage: compare years by the rate, not the count. Zero rows, with a message, when the CDE returns no data.

Examples

## Not run: 
# Oakland Police Department, California
get_police_employment("CA0010900", from = "2018", to = "2020")

# California, and the nation
get_police_employment(state_abb = "CA", from = "2018", to = "2020")
get_police_employment(from = "2018", to = "2020")

## End(Not run)

Get region-level NIBRS participation rate

Description

Aggregates get_state_participation() across every state in region_name. Census region membership is taken from the bundled fbi_api_agencies dataset – a fixed geography, not live crime data – while each state's participation counts are fetched live. See get_agency_participation() for why this is a modernized reimplementation rather than the retired year-by-year SRS/NIBRS participation series.

Usage

get_region_participation(region_name, key = get_api_key())

Arguments

region_name

String for the census region to get data for. See regions for valid values.

key

API key for the legacy FBI API (not needed for CDE API).

Value

A one-row data.frame with columns: region, total_agencies, nibrs_agencies, participation_rate.

Author(s)

Jared E. Knowles, Civilytics Consulting

See Also

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka(), get_leoka_monthly(), get_reported_arson(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_region_participation("South")

## End(Not run)

Get state- or national-level reported arson counts

Description

get_reported_crime() for arson (offense = "ARS"): reported sums, not the FBI's estimates. Called get_estimated_arson() until fbiCDE 0.2.0; the old name still works and warns.

Usage

get_reported_arson(
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  comparison = FALSE
)

Arguments

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

comparison

If TRUE, a state query also returns the national comparison series (rate only). Default FALSE returns only the state's own series. Has no effect on a national query.

Value

A data.frame with the columns described in get_agency_crime().

See Also

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka(), get_leoka_monthly(), get_region_participation(), get_reported_crime(), get_state_participation()

Examples

## Not run: 
get_reported_arson("CA")

## End(Not run)

Get state- or national-level reported crime counts

Description

Returns crime reported to the FBI: the sum of what the agencies that reported each month sent, in either format (NIBRS, or the older summary format). It is not the FBI's estimate, which adds a model's prediction for everything outside NIBRS. Compare participated_population with population to see how much of the state or nation a month covers. The FBI's state and national summary-format estimates are published as a bulk download only, which the package does not read; the download recipe fetches it.

Usage

get_reported_crime(
  state_abb = NULL,
  from = "01-2015",
  to = "12-2020",
  offense = "V",
  comparison = FALSE
)

Arguments

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2020").

offense

Offense code (default "V" for violent crime). See get_offense_codes() for available codes.

comparison

If TRUE, a state query also returns the national comparison series (rate only). Default FALSE returns only the state's own series. Has no effect on a national query.

Details

This function was called get_estimated_crime() until fbiCDE 0.2.0; the old name still works and warns.

Value

A data.frame with the columns described in get_agency_crime().

See Also

vignette("estimates") for reported, estimated and imputed crime.

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka(), get_leoka_monthly(), get_region_participation(), get_reported_arson(), get_state_participation()

Examples

## Not run: 
get_reported_crime("CA")

## End(Not run)

Get Supplemental Homicide Reports (SHR) offense counts

Description

Retrieves homicide offense counts from the FBI's Supplemental Homicide Reports via the CDE API endpoint ⁠shr/<level>⁠ with type=counts.

Usage

get_shr(ori = NULL, state_abb = NULL, from = "01-2015", to = "12-2015")

Arguments

ori

A string of the 9-character ORI code for the desired agency.

state_abb

String for state abbreviation. If NULL (default) returns national data.

from

Start date in MM-YYYY format (default "01-2015").

to

End date in MM-YYYY format (default "12-2015").

Value

A data.frame with columns: geography, period, count

Examples

## Not run: 
# Gets national-level SHR data
get_shr()

# Gets California state-level SHR data
get_shr(state_abb = "CA")

# Gets Oakland PD SHR data
get_shr(ori = "CA0010900")

## End(Not run)

Get state-level NIBRS participation rate

Description

See get_agency_participation() for why this is a modernized reimplementation (share of agencies currently reporting NIBRS) rather than the retired year-by-year SRS/NIBRS participation series.

Usage

get_state_participation(state_abb, key = get_api_key())

Arguments

state_abb

String input for the state abbreviation to get data for.

key

API key for the legacy FBI API (not needed for CDE API).

Value

A one-row data.frame with columns: state_abbr, total_agencies, nibrs_agencies, participation_rate.

Author(s)

Jared E. Knowles, Civilytics Consulting

See Also

Other UCR crime functions: get_agency_crime(), get_agency_participation(), get_leoka(), get_leoka_monthly(), get_region_participation(), get_reported_arson(), get_reported_crime()

Examples

## Not run: 
get_state_participation("MT")

## End(Not run)

Get state list from the CDE API

Description

Retrieves the list of states/territories from the CDE lookup endpoint.

Usage

get_states()

Value

A data.frame with state abbreviations and names.

Examples

## Not run: 
states <- get_states()
head(states)

## End(Not run)

How much of the FBI's published crime figure was estimated

Description

Compares the FBI's estimate for a state or the nation with the crime agencies reported to the FBI, and says how much of the estimate the FBI's model supplied. The FBI builds its estimate from NIBRS reports only and models everything else: agencies that did not report, and agencies that reported only in the older summary format. So the gap is measured against reported_nibrs, and reported_other shows the summary-format reports the model predicted rather than used.

Usage

imputation_gap(state_abb = NULL, year, offense = "V")

Arguments

state_abb

String for state abbreviation. If NULL (default) compares national figures.

year

One or more years, e.g. 2021:2022.

offense

A summary offense code: "V" (violent crime, the default), "P", "ROB", "ASS", "BUR", "LAR", "MVT", "ARS", "HOM" or "RPE".

Details

The API publishes estimates for 2021 and 2022 only (see nibrs_estimation_years), and for states and the nation only. A year it does not cover fails with the API's message listing the years it has.

reported and reported_nibrs differ a little even where every report arrived in NIBRS, because the two formats count offenses differently (for example, the summary format counts only the most serious offense in an incident). In Texas in 2022, where every report did, reported_other is about -1% of reported_nibrs for violent crime and within about 2% for every supported offense but burglary (about 6%); vignette("estimates") gives the table. A reported_other of that size, negative included, means nearly every report arrived in NIBRS. gap compares two NIBRS figures, so the counting difference does not enter it, but it is not exactly zero where little was modeled: for Texas's 2022 violent crime it is -0.7% of the estimate.

Each row takes one estimate request, one summarized request and one nibrs request per NIBRS offense code that makes up offense (six for violent crime).

Value

A data.frame with one row per year:

geography, year, offense

What was compared

reported

Crime reported to the FBI in either format: the year's sum from get_reported_crime()

reported_nibrs

Crime reported in NIBRS only

reported_other

reported - reported_nibrs: summary-format reports, plus the counting difference. Can be negative

coverage

Mean monthly share of the population covered by agencies reporting in either format

coverage_nibrs

The same, for agencies reporting in NIBRS

published, published_lower, published_upper

The FBI's estimate and the bounds of its confidence interval

gap, gap_lower, gap_upper

published - reported_nibrs: what the FBI's model supplied, with bounds from the estimate's interval

share_estimated, share_lower, share_upper

gap / published: the share of the published figure the model supplied, with bounds

See Also

vignette("estimates") for reported, estimated and imputed crime.

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

## Not run: 
# 2021, when the FBI accepted NIBRS reports only
imputation_gap("CA", year = 2021:2022)
imputation_gap(year = 2021:2022)

## End(Not run)

Impute reporting gaps in county crime detail data

Description

Fills temporal holes within agencies that report some periods but miss others. The values it imputes are this package's, from each agency's own neighboring months, not the FBI's estimate (see get_nibrs_estimate()). Operates on rate so a drifting denominator is respected: the rate is linearly interpolated across time (in months), then scaled by the gap month's own population to derive the imputed count. That is its participated_population when the CDE reports one, and otherwise its population: the CDE reports no participated population for a month the agency did not report, which is every gap. Agencies that never report in the window, or have no population (e.g. transit or campus police, whose rate is undefined), are left unchanged. Every filled value is flagged with imputed = TRUE and impute_method; its participated_population stays missing, so coverage figures from get_county_crime() still show the month as unreported.

Usage

impute_reporting_gaps(detail, method = "interpolate")

Arguments

detail

A data.frame as returned by get_county_crime_detail(), with at least the columns: ori, offense, period, count, population, participated_population, rate, reported.

method

Imputation method. Currently only "interpolate" is supported, which uses linear interpolation of rate across time (in months), then scales by each gap month's own population as described above. Gaps at the edges (before first or after last reported period) are not filled.

Details

This is an opt-in transform — the raw detail from get_county_crime_detail() stays pristine. Call this function explicitly when you need continuous series for trend analysis. Gaps at the edges (before first or after last reported period) are not filled; only gaps between known values are interpolated.

Value

A data.frame with the same rows and columns as detail, plus two new columns:

  • imputed: logical, TRUE only for rows whose values were filled by imputation; FALSE for all original (reported or missing) rows.

  • impute_method: character, the method name (e.g. "interpolate") on imputed rows; NA elsewhere.

See Also

vignette("estimates") for reported, estimated and imputed crime.

Examples

## Not run: 
detail <- get_county_crime_detail("Alameda", "CA", from = "01-2019", to = "12-2021")
filled <- impute_reporting_gaps(detail, method = "interpolate")
table(filled$reported, filled$imputed)

## End(Not run)

Validate an ORI code

Description

Checks if an ORI (Organization Request Identifier) matches the expected 9-character format: 2 letters followed by 7 alphanumerics (letters allowed for state, tribal, campus, and some city ORIs) (e.g. "CA0010900").

Usage

is_valid_ori(ori)

Arguments

ori

Character string or vector of ORI codes.

Value

Logical vector, TRUE for valid ORIs.

Examples

is_valid_ori("CA0010900")
is_valid_ori("CA001300X")
is_valid_ori("abc123")

Validate a state abbreviation

Description

Checks if a state abbreviation is a valid US state or territory code.

Usage

is_valid_state(state_abb)

Arguments

state_abb

Character string or vector of state abbreviations.

Value

Logical vector, TRUE for valid state abbreviations.

Examples

is_valid_state("CA")
is_valid_state("XX")

Join Census ACS population estimates to county crime detail

Description

Fetches an American Community Survey (ACS) total-population estimate for each county represented in detail, keyed by the county_fips column. Returns the detail frame with an added census_population column (integer). Counties without a FIPS match or without Census data get NA.

Usage

join_census_pop(
  detail,
  key = Sys.getenv("CENSUS_KEY"),
  year = as.integer(format(Sys.Date(), "%Y")) - 2L,
  dataset = "acs/acs5",
  census_fun = NULL
)

Arguments

detail

A data.frame as returned by get_county_crime_detail(), with at least the columns: county_name, state_abbr, and county_fips (the last supplied by county_agencies()).

key

Census API key. Defaults to the CENSUS_KEY environment variable. Obtain a free key from https://api.census.gov/data/key_signup.html.

year

ACS vintage year. Defaults to two years before the current year, because the ACS 5-year release for year Y does not publish until December of Y + 1.

dataset

Census dataset name passed to censusapi::getCensus(). Defaults to "acs/acs5"; use "acs/acs1" for the 1-year release.

census_fun

Function used to call the Census API. Defaults to censusapi::getCensus(). Exposed for testing; you should not need to set it.

Details

This is an optional feature requiring the censusapi package (in ‘Suggests’) and a free Census API key (set via the CENSUS_KEY environment variable or the key argument). Without censusapi, the function returns detail with an all-NA census_population column and a message.

The default dataset is the ACS 5-year release ("acs/acs5"). The 1-year release ("acs/acs1") only publishes estimates for geographies of 65,000+ people, which excludes roughly two-thirds of US counties — so 5-year is the correct default for a county denominator.

Value

The input detail data.frame with an additional census_population column (integer, one value per county). If censusapi is unavailable or the request fails, the column is all NA.

Examples

## Not run: 
detail <- get_county_crime_detail("Alameda", "CA",
                                  from = "01-2019", to = "12-2019")
detail_with_pop <- join_census_pop(detail)
agg <- get_county_crime(detail_with_pop, denominator = "census_pop")

## End(Not run)

List the metropolitan and micropolitan statistical areas

Description

Returns every CBSA in the bundled crosswalk, with how many counties each contains. This is the discovery counterpart to metro_agencies(): it answers "what may I pass as metro?"

Usage

list_metros(type = NULL)

Arguments

type

Optionally filter to "metro" (Metropolitan Statistical Areas) or "micro" (Micropolitan Statistical Areas). NULL (default) returns both.

Value

A data.frame with columns cbsa_code, cbsa_title, cbsa_type, and n_counties, carrying the delineation vintage in attr(x, "vintage").

See Also

metro_agencies(), counties_with_fips() for the county analogue.

Examples

head(list_metros(type = "metro"))

Returns a vector of all variable parameter options for get_nibrs_offender().

Description

Returns a vector of all variable parameter options for get_nibrs_offender().

Usage

list_nibrs_offender_variables()

Value

A character vector of all variable parameter options for get_nibrs_offender().

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

list_nibrs_offender_variables()

Returns a vector of all variable parameter options for get_nibrs_offense().

Description

Returns a vector of all variable parameter options for get_nibrs_offense().

Usage

list_nibrs_offense_variables()

Value

A character vector of all variable parameter options for get_nibrs_offense().

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offenses(), list_nibrs_victim_variables(), list_regions()

Examples

list_nibrs_offense_variables()

List the offense codes the NIBRS functions accept.

Description

List the offense codes the NIBRS functions accept.

Usage

list_nibrs_offenses()

Value

A data.frame with columns code and label: the summary groups ("V", "P", "ROB", "BUR", ...) and the NIBRS offense codes from the CDE's offense lookup. The API also accepts NIBRS offense codes missing from that lookup, such as "13A" (aggravated assault) or "120" (robbery).

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_victim_variables(), list_regions()

Examples

list_nibrs_offenses()

Returns a vector of all variable parameter options for get_nibrs_victim().

Description

Returns a vector of all variable parameter options for get_nibrs_victim().

Usage

list_nibrs_victim_variables()

Value

A character vector of all variable parameter options for get_nibrs_victim().

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_regions()

Examples

list_nibrs_victim_variables()

Return a vector of all regions choices.

Description

Return a vector of all regions choices.

Usage

list_regions()

Value

A vector of all regions choices.

See Also

Other NIBRS functions: get_nibrs_estimate(), get_nibrs_offender(), get_nibrs_offense(), get_nibrs_victim(), imputation_gap(), list_nibrs_offender_variables(), list_nibrs_offense_variables(), list_nibrs_offenses(), list_nibrs_victim_variables()

Examples

list_regions()

List the offense names get_arrest_count() accepts

Description

The CDE reports arrests at three levels of detail, and get_arrest_count() and get_arrest_demographics() accept a name from any of them. Three names it lists, "Rape", "Rape - Not Specified" and "Runaway", have no arrests in the API; see ucr_arrest_offense_codes for the codes behind the rest.

Usage

list_ucr_arrest_offenses(level = c("all", "name", "category", "breakdown"))

Arguments

level

"all" (the default) for every name, or one level: "name" (the 34 offense names, e.g. "Drug Possession"), "category" (29, e.g. "Drug/Narcotic Offenses") or "breakdown" (49, e.g. "Drug Possession - Marijuana"). Within a level the counts do not overlap, so ranking offenses means ranking one level.

Value

A sorted character vector of offense names.

See Also

Other UCR arrest functions: get_arrest_count(), get_arrest_demographics(), get_arrest_demographics_all()

Examples

list_ucr_arrest_offenses()
list_ucr_arrest_offenses("category")

List the law-enforcement agencies in a metropolitan area

Description

Resolves a Core Based Statistical Area (CBSA) to the union of its member counties' agency sets. A metro is a set of whole counties, so this simply stacks county_agencies() across them, and agency_class keeps exactly its county-level meaning.

Usage

metro_agencies(metro, state = NULL)

Arguments

metro

A CBSA title (e.g. "Pittsburgh, PA"), or a short name ("Pittsburgh"). See list_metros() for the available values.

state

Optional two-letter state abbreviation, used only to disambiguate an ambiguous short name.

Details

CBSA titles are unique nationally, so state is only needed to disambiguate a short name shared by several metros ("Albany" matches GA, OR and NY).

Value

A data.frame with the county_agencies() columns plus cbsa_code, cbsa_title, cbsa_type ("metro"/"micro"), and central_outlying (whether the agency's county is central or outlying in the CBSA). Each ORI appears once: an agency that polices several member counties is attributed to the first of them in delineation order, and its agency_county_names lists all of them. Returns a zero-row frame with a warning when the metro is unknown.

Coverage limitations

The bundled crosswalk has 1,915 county-CBSA rows, about 61% of the 3,143 counties and county equivalents known to county_agencies(). That row count overstates coverage slightly, because Puerto Rico's municipios never join a CDE county name (see below). Counted as distinct, CDE-reachable counties instead, coverage is about 58.6% (1,843 of 3,143). Either way, rural counties belong to no CBSA at all; that is a property of the 2023 OMB delineation, not a gap in the data.

Connecticut's metros are built from its nine planning regions, the county equivalents it adopted in 2022, and its agencies are attributed to their planning region as the CDE reports it (see county_agencies()). Two Connecticut campus agencies have no region in the CDE's directory, Yale and UConn Health, so the New Haven and Hartford metros lack them.

Puerto Rico's 10 CBSAs are unmapped, but that is academic: the CDE has exactly one Puerto Rico agency.

Agencies whose county_name is "N/A" – mostly state police, other state agencies and tribal agencies – cannot be reached from any county-keyed geography. Three that police a whole county-equivalent are attributed by the package instead (the NYPD, DC's Metropolitan Police and the Baltimore City Sheriff; see county_agencies()), so the New York and Washington metros include them.

See Also

list_metros() to discover metro names, county_agencies().

Examples

## Not run: 
metro_agencies("Pittsburgh, PA")

## End(Not run)

Offenses ("indicators") the FBI's NIBRS estimates cover.

Description

Built from nibrs-estimation/lookup/all by data-raw/api_vocabularies.R. get_nibrs_estimate() accepts an id from this table, or one of the summary codes "V", "P", "ROB", "ASS", "BUR", "LAR", "MVT", "ARS", "HOM" and "RPE".

Usage

nibrs_estimation_indicators

Format

A data frame with 71 rows and 3 variables:

group

The lookup's group: "Person", "Property", "Society" or "GroupB"

indicator

Offense name, e.g. "Violent Crime"

id

The estimates API's indicator ID, e.g. 133

Source

https://cde.ucr.cjis.gov/LATEST/nibrs-estimation/lookup/all


States the FBI's NIBRS estimates cover, with their estimate IDs.

Description

The estimates API identifies a state by its own number, in roughly alphabetical order of the postal code (Alaska 1, Alabama 2, California 6), not by FIPS. Built from nibrs-estimation/lookup/all by data-raw/api_vocabularies.R. The lookup's "Federal" and "Other" entries have no state abbreviation and are left out.

Usage

nibrs_estimation_states

Format

A data frame with 57 rows and 3 variables:

state_abbr

Postal abbreviation, as passed to state_abb

state_name

Name as the lookup gives it

id

The estimates API's state ID

Source

https://cde.ucr.cjis.gov/LATEST/nibrs-estimation/lookup/all


Years the FBI's NIBRS estimates cover in the API.

Description

Built from nibrs-estimation/lookup/all by data-raw/api_vocabularies.R. The API publishes estimates for 2021 and 2022 only; a live test fails when the FBI adds a year, so the package can be rebuilt.

Usage

nibrs_estimation_years

Format

An integer vector.

Source

https://cde.ucr.cjis.gov/LATEST/nibrs-estimation/lookup/all


All available variables for NIBRS offender data.

Description

The values get_nibrs_offender() accepts for variable: the keys of a NIBRS response's offender section. Built by data-raw/api_vocabularies.R.

Usage

nibrs_offender_variables

Format

A character vector with 4 elements.

Source

https://cde.ucr.cjis.gov/LATEST/


All available variables for NIBRS offense data.

Description

The values get_nibrs_offense() accepts for variable: the keys of a NIBRS response's offense section. Built by data-raw/api_vocabularies.R.

Usage

nibrs_offense_variables

Format

A character vector with 2 elements.

Source

https://cde.ucr.cjis.gov/LATEST/


Offense codes the NIBRS functions accept.

Description

The summary groups ("V", "P", "ROB", "BUR", ...) and the NIBRS offense codes from the CDE's offense lookup. The API also accepts NIBRS codes missing from the lookup, such as "13A" or "120". Built by data-raw/api_vocabularies.R.

Usage

nibrs_offenses

Format

A data frame with 73 rows and 2 variables:

code

Offense code, as passed to offense

label

Offense name

Source

https://cde.ucr.cjis.gov/LATEST/


All available variables for NIBRS victim data.

Description

The values get_nibrs_victim() accepts for variable: the keys of a NIBRS response's victim section. Built by data-raw/api_vocabularies.R.

Usage

nibrs_victim_variables

Format

A character vector with 6 elements.

Source

https://cde.ucr.cjis.gov/LATEST/


List the law-enforcement agencies attributed to a place

Description

Resolves a municipality to the agency that reports crime for it. CDE city agencies are named "<Place> Police Department", so the place name is recovered from the agency name — the agency is the place. This is an attribution model, not a spatial one.

Usage

place_agencies(place, state, county = NULL)

Arguments

place

Place name (case-insensitive; e.g. "Lufkin"). Supply either the bare name or the full agency name — both resolve.

state

Two-letter state abbreviation (e.g. "TX").

county

Optional county name, needed only to disambiguate a place name that occurs in more than one county of the same state.

Details

Sheriffs, state police, and tribal agencies are never place members: a sheriff's population is the unincorporated remainder, and contract cities report under their own city ORI. A place's crime is therefore carried entirely by its own agency, with no double-count and no gap.

Campus and special-district agencies sit inside places but cannot be attributed from names alone (name-matching achieves only ~26% recall). Add them with add_place_spatial_members(), which is opt-in and requires sf and tigris.

Value

A data.frame with columns ori, agency_name, agency_type_name, agency_class, place_name, place_type, place_fips, cousub_fips, county_name, state_abbr, attribution, latitude, longitude. attribution records how the row earned membership: "name_identity" here, or "point_in_polygon" for rows added by add_place_spatial_members(). Returns a zero-row frame (with a warning) when no municipal agency matches.

Census codes

Each agency carries the Census code of the unit it polices, for joining Census data:

  • place_fips: the 7-digit place code (2-digit state + 5-digit place), when the agency polices a Census place. place_type is then "incorporated", or "cdp" for the few agencies whose only match is a census-designated place.

  • cousub_fips: the 10-digit county subdivision code (state + county + subdivision), when the agency polices a township, or a New England or New York town. Those are governments but not Census places; place_type is then "county_subdivision" and place_fips is NA.

Codes are matched by name within the agency's state, and only among Census units lying in one of the agency's own counties; an incorporated place wins over a county subdivision, which wins over a CDP. 98.7% of the 11,646 municipal agencies resolve. The rest – regional and multi-municipality departments, and two names that match more than one unit in their county – get NA rather than a guess. Codes follow the Census vintage in PLACE_VINTAGE; Connecticut's county subdivision codes are therefore the 2020 ones, under its old counties, while Census data from 2022 codes them under its planning regions.

See Also

county_agencies() for the county-level resolver, get_place_crime_detail() for the crime series.

Examples

place_agencies("Lufkin", "TX")

The Census vintage of the bundled place crosswalk

Description

place_agencies() gives each municipal agency the Census code of the place or county subdivision it polices, from a crosswalk built from the Census Bureau's 2020 reference code files (see data-raw/place_fips_crosswalk.R). Places are occasionally incorporated, merged or dissolved, so codes are only guaranteed against this vintage. Read from the shipped crosswalk's own "vintage" attribute when the package loads.

Usage

PLACE_VINTAGE

Format

An integer scalar.


Regions available to get estimated UCR and NIBRS data for.

Description

Some functions let you get regional estimated data and require a string input for which region you want data from. This is a vector of strings for the six regions available.

Usage

regions

Format

A vector with 6 elements:

Source

https://cde.ucr.cjis.gov/LATEST/


Sets the FBI's Crime Data Explorer API key

Description

Deprecated. The current CDE API (⁠cde.ucr.cjis.gov/LATEST/⁠) does not require an API key. This function is retained only for backward compatibility with code that previously used the legacy api.data.gov-hosted API.

Usage

set_api_key(key)

Arguments

key

A character string with the API key (ignored).

Value

NULL. A deprecation message is printed on every call.

Examples

## Not run: 
set_api_key("abc123")

## End(Not run)

Arrest offense codes

Description

The CDE's arrest endpoint addresses one offense by numeric code (⁠arrest/<level>/<code>⁠); an offense name is rejected. Each code is one breakdown, and reports its arrests under one offense name and one category. get_arrest_count() and get_arrest_demographics() resolve a name at any level to its codes and sum them. Built by data-raw/api_vocabularies.R from the lookup/offenses?type=arrest codes (plus Suspicion, 320, which the lookup omits), placing each by the names its own response reports. Three names in ucr_arrest_offenses, "Rape", "Rape - Not Specified" and "Runaway", have no code and no arrests.

Usage

ucr_arrest_offense_codes

Format

A data frame with 47 rows and 5 variables:

code

The code, as a string

label

The CDE lookup's label for it

name

The offense name it reports under

category

The category it reports under

breakdown

The breakdown it reports under

Source

https://cde.ucr.cjis.gov/LATEST/


All offenses available to get UCR arrest counts for.

Description

The offense names get_arrest_count() accepts: every key of the three maps in the CDE's arrest totals response, with the map it comes from. A name can appear at more than one level. Use list_ucr_arrest_offenses() to list them. Built by data-raw/api_vocabularies.R.

Usage

ucr_arrest_offenses

Format

A data frame with 112 rows and 2 variables:

offense

Offense name, as passed to get_arrest_count(offense = )

level

"name" (34), "category" (29) or "breakdown" (49)

Source

https://cde.ucr.cjis.gov/LATEST/