ei_summary: Compute ecological inference summaries from ballot microdata

View source: R/ei_summary.R

ei_summaryR Documentation

Compute ecological inference summaries from ballot microdata

Description

Builds the objects needed for ecological inference over a set of races: marginal distributions per precinct for each race, a joint contingency array across all races and precincts, and its precinct-aggregated versions.

Usage

ei_summary(
  elections,
  data = NULL,
  source = NULL,
  format = c("lphom", "eipack")
)

Arguments

elections

Character vector of race codes (e.g. c("PRE", "USS")). All codes must be keys in election_catalog.

data

Optional data.frame. If provided, it must contain columns COUNTY, PRECINCT, and all codes in elections. If NULL (default), data are loaded automatically via get_election_data().

source

Character string or NULL. Data source override; see get_county_data(). Ignored when data is provided.

format

Character. Output format for the margins element:

  • "lphom" (default): a named list of data.frames, one per race. Compatible with lphom and related packages.

  • "eipack": a single wide data.frame with all races side by side (columns named ⁠<RACE>_<OPTION>⁠, e.g. PRE_R, PRE_D).

Details

All summaries share a common intersection universe: voters who were eligible to vote in every race in elections (i.e. non-NA in all selected columns). To obtain the full universe of a single race, pass only that race.

Vote codes

In the microdata, "A" denotes a blank vote and "I" an invalid vote; both are included as active categories. NA means the voter was not eligible in that race and defines the universe boundary.

Multi-member races

For races where voters could select more than one candidate (e.g. "HOS3"), each observed combination (e.g. "BauDuf") is treated as an atomic category. See election_catalog for the candidates field listing the individual candidates on the ballot.

Subsetting

Use the [ operator to extract a subset of races from an existing ei_summary object without reloading data:

obj3 <- ei_summary(c("PRE", "USS", "HOS3"))
obj2 <- obj3[c("PRE", "USS")]   # subset to 2 races

Value

An object of class "ei_summary" (a named list) with components:

margins

Marginal distributions per precinct. A named list of data.frames (format "lphom") or a single wide data.frame (format "eipack"). Each data.frame contains columns precinct_id, county_id, n_voters, and one column per vote option. n_voters is identical across all races because the universe is shared.

joint_precinct

Integer array of dimensions ⁠[opt_1 x ... x opt_k x precincts]⁠. NULL when only one race is requested. Summing over any race dimension reproduces the corresponding margin.

joint_total

Same array collapsed over precincts: ⁠[opt_1 x ... x opt_k]⁠. NULL when only one race is requested.

meta

Named list of metadata: elections, counties, n_precincts, n_voters, opt_levels, format, precinct_info, created_at.

See Also

ei_summary_random()] get_election_data(), get_county_data(), to_lphom(), to_eipack(), list_elections()

Examples

# Using the built-in example dataset
obj <- ei_summary(c("PRE", "USS"), data = example_ballots)
print(obj)
summary(obj)


# Single race: margins only, no joint array
pres <- ei_summary("PRE")
summary(pres)

# Two races: margins + 3-D joint array [PRE x USS x precinct]
obj <- ei_summary(c("PRE", "USS"))
print(obj)
summary(obj)
dim(obj$joint_precinct)

# Three races
obj3 <- ei_summary(c("PRE", "USS", "HOS3"))
dim(obj3$joint_precinct)   # [opts_PRE x opts_USS x opts_HOS3 x n_precincts]

# Wide format for eipack-style packages
obj_wide <- ei_summary(c("PRE", "USS"), format = "eipack")



eiballots documentation built on Sept. 26, 2026, 5:06 p.m.