# Getting Started with rict

    library(rict)

## Overview

`rict` produces clean, publication-ready tables for redistricting analysis. It is designed to accompany maps from `redist` and related packages, summarizing district-level data on population, demographics, elections, compactness, contiguity, and administrative splits.

The package builds on two core R table libraries:

- `gt` for formatted HTML output
- `tibble` for data-frame output (set `as_gt = FALSE`)

## Data

`rict` ships with two example datasets from West Virginia:

- `wv`: a `redist_map` object with county-level demographic, partisan, and geographic data
- `wv_plans`: a `redist_plans` object with sampled redistricting plans and the enacted 2020 congressional plan

    data(wv)
    data(wv_plans)

## Quick start with `rict()`

The simplest entry point is `rict()`, which creates a summary table from a `redist_map` or `redist_plans` object:

    rict(wv)
    #> Warning: There was 1 warning in `dplyr::summarize()`.
    #> ℹ In argument: `dplyr::across(where(is.numeric), sum, na.rm = TRUE)`.
    #> ℹ In group 1: `district = 1`.
    #> Caused by warning:
    #> ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
    #> Supply arguments directly to `.fns` through an anonymous function instead.
    #>
    #>   # Previously
    #>   across(a:b, mean, na.rm = TRUE)
    #>
    #>   # Now
    #>   across(a:b, \(x) mean(x, na.rm = TRUE))
    #> ℹ The deprecated feature was likely used in the redist package.
    #>   Please report the issue at <https://github.com/alarm-redist/redist/issues>.

district | pop | pop_white | pop_black | pop_hisp | pop_aian | pop_asian | pop_nhpi | pop_other | pop_two | vap | vap_white | vap_black | vap_hisp | vap_aian | vap_asian | vap_nhpi | vap_other | vap_two | cd_2010 | cd_2020 | pre_20_rep_tru | pre_20_dem_bid | ndv | adv_20 | nrv | arv_20 | sample_1 | sample_2 | sample_3 | sample_4 | sample_5 | sample_6 | sample_7 | sample_8 | sample_9 | sample_10 | sample_11 | sample_12 | state
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
1 | 896067 | 805369 | 36345 | 11331 | 1632 | 6132 | 155 | 2136 | 32967 | 715682 | 649695 | 29039 | 7866 | 1426 | 5030 | 116 | 1294 | 21216 | 73 | 28 | 273523 | 112947 | 112947 | 112947 | 273523 | 273523 | 37 | 31 | 36 | 35 | 38 | 33 | 35 | 36 | 31 | 31 | 37 | 36 | WV
2 | 897649 | 793465 | 28404 | 23496 | 1555 | 8771 | 274 | 2516 | 39168 | 717250 | 643345 | 22963 | 15617 | 1335 | 7203 | 217 | 1687 | 24883 | 35 | 54 | 271859 | 123037 | 123037 | 123037 | 271859 | 271859 | 52 | 53 | 50 | 53 | 51 | 51 | 53 | 53 | 53 | 52 | 51 | 53 | WV

For a `redist_plans` object, specify which plan to display:

    rict(wv_plans, "cd_2020")

district | total_pop | chain | pop_overlap | total_vap | plan_dev | comp_edge | comp_polsby | pop_white | pop_black | pop_hisp | pop_aian | pop_asian | pop_nhpi | pop_other | pop_two | vap_white | vap_black | vap_hisp | vap_aian | vap_asian | vap_nhpi | vap_other | vap_two | pre_20_rep_tru | pre_20_dem_bid | adv_20 | arv_20 | county_splits | ndv | nrv | ndshare | e_dvs | pr_dem | e_dem | pbias | egap
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
1 | 896067 | NA | 1 | 715682 | 0.000881968 | 0.94 | 0.26271 | 805369 | 36345 | 11331 | 1632 | 6132 | 155 | 2136 | 32967 | 649695 | 29039 | 7866 | 1426 | 5030 | 116 | 1294 | 21216 | 273523 | 112947 | 112947 | 273523 | 0 | 112947 | 273523 | 0.2923 | 0.2923 | 0 | 0 | 0 | 0.104
2 | 897649 | NA | 1 | 717250 | 0.000881968 | 0.94 | 0.13358 | 793465 | 28404 | 23496 | 1555 | 8771 | 274 | 2516 | 39168 | 643345 | 22963 | 15617 | 1335 | 7203 | 217 | 1687 | 24883 | 271859 | 123037 | 123037 | 271859 | 0 | 123037 | 271859 | 0.3116 | 0.3116 | 0 | 0 | 0 | 0.104

## Specialized tables

For more targeted analysis, use the `rict_*` family of functions. Each accepts a `map` and `plan` argument, and returns either a `gt` table (default) or a tibble.

### Population parity

`rict_population()` shows total population per district and deviation from the ideal (equal) population:

    rict_population(map = wv, plan = wv$cd_2020)

District | Population | Deviation
--- | --- | ---
People | %
1 | 896,067 | −791 | −0.1%
2 | 897,649 | 791 | 0.1%

### Demographics

`rict_demographics()` breaks down population and voting-age population (VAP) by race and ethnicity. By default, subcategory columns are normalized to proportions:

    rict_demographics(map = wv, plan = wv$cd_2020)

District | Total Population | Voting Age Population
--- | --- | ---
Pop. | White | Black | Hispanic | Native | Asian | NH/PI | Other | Two+ | VAP | White | Black | Hispanic | Native | Asian | NH/PI | Other | Two+
1 | 896,067 | 89.9% | 4.1% | 1.3% | 0.2% | 0.7% | 0.0% | 0.2% | 3.7% | 715,682 | 90.8% | 4.1% | 1.1% | 0.2% | 0.7% | 0.0% | 0.2% | 3.0%
2 | 897,649 | 88.4% | 3.2% | 2.6% | 0.2% | 1.0% | 0.0% | 0.3% | 4.4% | 717,250 | 89.7% | 3.2% | 2.2% | 0.2% | 1.0% | 0.0% | 0.2% | 3.5%

Set `normalize = FALSE` to see raw counts:

    rict_demographics(map = wv, plan = wv$cd_2020, normalize = FALSE)

District | Total Population | Voting Age Population
--- | --- | ---
Pop. | White | Black | Hispanic | Native | Asian | NH/PI | Other | Two+ | VAP | White | Black | Hispanic | Native | Asian | NH/PI | Other | Two+
1 | 896,067 | 80,536,900.0% | 3,634,500.0% | 1,133,100.0% | 163,200.0% | 613,200.0% | 15,500.0% | 213,600.0% | 3,296,700.0% | 715,682 | 64,969,500.0% | 2,903,900.0% | 786,600.0% | 142,600.0% | 503,000.0% | 11,600.0% | 129,400.0% | 2,121,600.0%
2 | 897,649 | 79,346,500.0% | 2,840,400.0% | 2,349,600.0% | 155,500.0% | 877,100.0% | 27,400.0% | 251,600.0% | 3,916,800.0% | 717,250 | 64,334,500.0% | 2,296,300.0% | 1,561,700.0% | 133,500.0% | 720,300.0% | 21,700.0% | 168,700.0% | 2,488,300.0%

### Elections

`rict_elections()` summarizes partisan election data. It automatically detects individual contest columns (e.g., `pre_20_dem_bid`), cycle-average columns (`adv_20`, `arv_20`), and normal vote columns (`ndv`, `nrv`), computing Democratic vote share for each:

    rict_elections(map = wv, plan = wv$cd_2020)

District | Average Dem. Vote Share | Contests Dem. Vote Share | Cycle Dem. Vote Share
--- | --- | --- | ---
Pre-Average | Pres 2020 | 2020
1 | 29.2% | 29.2% | 29.2%
2 | 31.2% | 31.2% | 31.2%

### Compactness

`rict_compactness()` computes geometric compactness measures via `redistmetrics`. The default measures are Polsby-Popper, Schwartzberg, Reock, and Convex Hull:

    rict_compactness(map = wv, plan = wv$cd_2020)

District | Polsby-Popper | Schwartzberg | Reock | Convex Hull
--- | --- | --- | --- | ---
1 | 35.0% | 59.2% | 46.8% | 79.6%
2 | 17.4% | 41.7% | 26.7% | 50.1%

You can supply custom measures as a named list of functions:

    rict_compactness(
      map = wv, plan = wv$cd_2020,
      measures = list(
        "comp_polsby" = redistmetrics::comp_polsby,
        "comp_lw" = redistmetrics::comp_lw
      )
    )

District | Polsby-Popper | Length Width
--- | --- | ---
1 | 35.0% | 70.0%
2 | 17.4% | 71.8%

### Contiguity

`rict_contiguity()` checks how many connected pieces each district has:

    rict_contiguity(map = wv, plan = wv$cd_2020)

District | Pieces
--- | ---
1 | 1
2 | 1

### Administrative splits

`rict_splits()` counts how administrative boundaries (e.g., counties, states) are split across districts:

    rict_splits(map = wv, plan = wv$cd_2020, admin = "state")

District | admin_state | total_state | multi_state
--- | --- | --- | ---
1 | 1 | 1 | 0
2 | 1 | 1 | 0

### Component populations

`rict_component()` breaks down population by administrative unit within each district:

    rict_component(map = wv, plan = wv$cd_2020, admin = "county")

county | pop
--- | ---
1
005 | 21,809
007 | 12,447
011 | 94,350
013 | 6,229
015 | 8,051
019 | 40,488
021 | 7,408
025 | 32,977
035 | 27,791
039 | 180,745
043 | 20,463
045 | 32,567
047 | 19,111
053 | 25,453
055 | 59,664
059 | 23,568
063 | 12,376
067 | 24,604
071 | 6,143
075 | 7,869
079 | 57,440
081 | 74,591
087 | 14,028
089 | 11,959
099 | 38,982
101 | 8,378
105 | 5,194
109 | 21,382
2
001 | 15,465
003 | 122,076
009 | 22,559
017 | 7,808
023 | 10,976
027 | 23,093
029 | 29,095
031 | 14,299
033 | 65,921
037 | 57,701
041 | 17,033
049 | 56,205
051 | 30,591
057 | 26,938
061 | 105,822
065 | 17,063
069 | 42,425
073 | 7,653
077 | 34,216
083 | 27,932
085 | 8,444
091 | 16,705
093 | 6,762
095 | 8,313
097 | 23,816
103 | 14,442
107 | 84,296

## Getting tibbles instead of gt tables

Every `rict_*` function accepts `as_gt = FALSE` to return a tibble instead of a `gt` table, making it easy to use the results for further computation:

    rict_elections(map = wv, plan = wv$cd_2020, as_gt = FALSE)
    #> # A tibble: 2 × 4
    #>   District ndshare pre_20 avg_20
    #>      <int>   <dbl>  <dbl>  <dbl>
    #> 1        1   0.292  0.292  0.292
    #> 2        2   0.312  0.312  0.312

## Extending gt tables

`rict` provides several helpers for working with `gt` tables:

### Partisan color scales

`data_color_party()` applies a red-to-blue color scale for Democratic vote share columns:

    rict(wv_plans, "cd_2020") |>
      data_color_party(columns = "e_dvs")

district | total_pop | chain | pop_overlap | total_vap | plan_dev | comp_edge | comp_polsby | pop_white | pop_black | pop_hisp | pop_aian | pop_asian | pop_nhpi | pop_other | pop_two | vap_white | vap_black | vap_hisp | vap_aian | vap_asian | vap_nhpi | vap_other | vap_two | pre_20_rep_tru | pre_20_dem_bid | adv_20 | arv_20 | county_splits | ndv | nrv | ndshare | e_dvs | pr_dem | e_dem | pbias | egap
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
1 | 896067 | NA | 1 | 715682 | 0.000881968 | 0.94 | 0.26271 | 805369 | 36345 | 11331 | 1632 | 6132 | 155 | 2136 | 32967 | 649695 | 29039 | 7866 | 1426 | 5030 | 116 | 1294 | 21216 | 273523 | 112947 | 112947 | 273523 | 0 | 112947 | 273523 | 0.2923 | 0.2923 | 0 | 0 | 0 | 0.104
2 | 897649 | NA | 1 | 717250 | 0.000881968 | 0.94 | 0.13358 | 793465 | 28404 | 23496 | 1555 | 8771 | 274 | 2516 | 39168 | 643345 | 22963 | 15617 | 1335 | 7203 | 217 | 1687 | 24883 | 271859 | 123037 | 123037 | 271859 | 0 | 123037 | 271859 | 0.3116 | 0.3116 | 0 | 0 | 0 | 0.104

### Geometry plots

`gt_plot_sf()` embeds small maps of `sf` geometries into a `gt` table:

    wv_dist <- wv |> dplyr::group_by(cd_2020) |> dplyr::summarize()
    gt::gt(wv_dist) |> gt_plot_sf()

cd_2020 | geom
--- | ---
1 |
2 |

### Compactness plots

`gt_plot_compactness()` adds visual compactness overlays (e.g., equal-area circles, convex hulls) to a table of compactness metrics:

    rict(wv_plans, "cd_2020") |>
      gt_plot_compactness(wv, wv$cd_2020)

district | total_pop | chain | pop_overlap | total_vap | plan_dev | comp_edge | comp_polsby | pop_white | pop_black | pop_hisp | pop_aian | pop_asian | pop_nhpi | pop_other | pop_two | vap_white | vap_black | vap_hisp | vap_aian | vap_asian | vap_nhpi | vap_other | vap_two | pre_20_rep_tru | pre_20_dem_bid | adv_20 | arv_20 | county_splits | ndv | nrv | ndshare | e_dvs | pr_dem | e_dem | pbias | egap | gg_polsby
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
1 | 896067 | NA | 1 | 715682 | 0.000881968 | 0.94 | 0.26271 | 805369 | 36345 | 11331 | 1632 | 6132 | 155 | 2136 | 32967 | 649695 | 29039 | 7866 | 1426 | 5030 | 116 | 1294 | 21216 | 273523 | 112947 | 112947 | 273523 | 0 | 112947 | 273523 | 0.2923 | 0.2923 | 0 | 0 | 0 | 0.104 |
2 | 897649 | NA | 1 | 717250 | 0.000881968 | 0.94 | 0.13358 | 793465 | 28404 | 23496 | 1555 | 8771 | 274 | 2516 | 39168 | 643345 | 22963 | 15617 | 1335 | 7203 | 217 | 1687 | 24883 | 271859 | 123037 | 123037 | 271859 | 0 | 123037 | 271859 | 0.3116 | 0.3116 | 0 | 0 | 0 | 0.104 |

### Other gt utilities

- `gt_get_data()`: extract the underlying tibble from a `gt` table
- `gt_hide_lists()`: hide list-columns (e.g., adjacency lists) from display

    tab <- rict(wv)
    gt_get_data(tab)
    #> # A tibble: 2 × 40
    #>   district    pop pop_white pop_black pop_hisp pop_aian pop_asian pop_nhpi
    #>      <int>  <dbl>     <dbl>     <dbl>    <dbl>    <dbl>     <dbl>    <dbl>
    #> 1        1 896067    805369     36345    11331     1632      6132      155
    #> 2        2 897649    793465     28404    23496     1555      8771      274
    #> # ℹ 32 more variables: pop_other <dbl>, pop_two <dbl>, vap <dbl>,
    #> #   vap_white <dbl>, vap_black <dbl>, vap_hisp <dbl>, vap_aian <dbl>,
    #> #   vap_asian <dbl>, vap_nhpi <dbl>, vap_other <dbl>, vap_two <dbl>,
    #> #   cd_2010 <int>, cd_2020 <int>, pre_20_rep_tru <dbl>, pre_20_dem_bid <dbl>,
    #> #   ndv <dbl>, adv_20 <dbl>, nrv <dbl>, arv_20 <dbl>, sample_1 <int>,
    #> #   sample_2 <int>, sample_3 <int>, sample_4 <int>, sample_5 <int>,
    #> #   sample_6 <int>, sample_7 <int>, sample_8 <int>, sample_9 <int>, …