The Deschutes County Commission formed the District Mapping Advisory Committee (DMAC) to develop a plan for splitting the county into 5 commissioner districts. The resulting map called “Plan C” by the committee has been submitted to the county commission. You can view the map and partisan lean at the Dave’s Redistricting website
County wide Democratic vote share in 2024 presidential election was 53.47%. The plan proposed by the DMAC favors Republicans in 3 of the 5 districts. This discrepancy shows that the proposed map favors Republican candidates when compared to at large elections. But is the map gerrymandered? The partisan bias could be the natural result of geography and voter distribution across the county rather than intentional crafting.
To address this question we generate 20,000 district plans that follow requirements for population parity, continuity, and use of existing precinct boundaries. Simulating district plans allows for an apples to apples comparison with the DMAC’s proposed districts. We compare the Democratic vote share in the simulated districts to the DMAC proposed map. Partisan vote share is based on the results of the 2024 presidential election.
This comparison shows the partisan bias of the committees proposed districts is not an inevitable result of county geography. The DMAC proposal packs Democratic voters into two districts, leaving three districts that favor Republican candidates. Only around 8% of the simulated district plans produced 3 seats that favored Republicans.
The code and data used for this analysis is available here. https://drive.google.com/drive/folders/1sRVrttp4ZBPGu1qT6UXP9V1p6XSFUyYw?usp=share_link (link must be copied into browser)
Original Precinct Data (Downloaded Sep. 17th 2025), Deschutes County Data Portal
Voter Registration and Census Population from DMAC handout
2024 Presidential Election Results pages 12 and 13 of canvass report
Data formatted for analysis in r here https://drive.google.com/drive/folders/1sRVrttp4ZBPGu1qT6UXP9V1p6XSFUyYw?usp=share_link (link must be copied into browser)
| PRECINCT | City | DES_2020_Census_Pop | Vote_Reg_2022 | Vote_Reg_2025 | OptionCDistrict |
|---|---|---|---|---|---|
| 1 | Bend | 3594 | 2895 | 2891 | D |
| 2 | Bend | 4897 | 3724 | 3985 | C |
| 3 | Bend | 5993 | 4346 | 4715 | D |
| 4 | Bend | 4691 | 4018 | 3937 | D |
| 5 | Bend | 8546 | 5151 | 5480 | D |
| 6 | Bend | 5534 | 3869 | 3856 | B |
| 7 | Bend | 2120 | 1605 | 1747 | D |
| 8 | Unincorporated | 811 | 746 | 966 | D |
| 9 | Bend | 3780 | 2790 | 2729 | B |
| 10 | Unincorporated | 82 | 45 | 53 | C |
| 11 | Bend | 1651 | 1522 | 1757 | D |
| 12 | Unincorporated | 985 | 899 | 878 | A |
| 13 | Unincorporated | 4620 | 3690 | 3770 | A |
| 14 | Unincorporated | 2091 | 1838 | 1865 | A |
| 15 | Unincorporated | 2810 | 2642 | 2653 | A |
| 16 | Unincorporated | 1712 | 1597 | 1532 | C |
| 17 | Redmond | 10363 | 5363 | 8589 | E |
| 18 | Unincorporated | 4588 | 4036 | 4068 | A |
| 19 | Unincorporated | 1645 | 1462 | 1456 | E |
| 20 | Bend | 8195 | 5648 | 5938 | A |
| 21 | Bend | 4163 | 3435 | 3571 | A |
| 22 | Unincorporated | 186 | 370 | 367 | A |
| 23 | La Pine | 2512 | 1826 | 2328 | C |
| 24 | Unincorporated | 1779 | 1313 | 1318 | C |
| 25 | Bend | 7221 | 5134 | 5546 | B |
| 26 | Bend | 3755 | 2607 | 3290 | B |
| 27 | Bend | 3215 | 2575 | 2922 | D |
| 28 | Redmond | 5706 | 4033 | 4263 | E |
| 29 | Redmond | 7207 | 5589 | 6598 | E |
| 30 | Sisters | 3064 | 2783 | 3217 | A |
| 31 | Unincorporated | 3427 | 3237 | 3374 | A |
| 32 | Bend | 4617 | 3229 | 3462 | B |
| 33 | Bend | 5286 | 3952 | 4316 | C |
| 34 | Bend | 6102 | 4470 | 4484 | B |
| 35 | Bend | 5632 | 4425 | 5010 | D |
| 36 | Redmond | 10019 | 9704 | 7584 | E |
| 37 | Unincorporated | 1543 | 1337 | 1378 | A |
| 38 | Unincorporated | 2580 | 1816 | 1807 | C |
| 39 | Unincorporated | 8025 | 7066 | 7176 | C |
| 40 | Unincorporated | 1484 | 1587 | 1636 | C |
| 41 | Unincorporated | 1004 | 791 | 773 | A |
| 42 | Unincorporated | 5235 | 4451 | 4494 | C |
| 43 | Unincorporated | 3641 | 3201 | 3330 | C |
| 44 | Bend | 5160 | 3890 | 3987 | B |
| 45 | Unincorporated | 1328 | 1112 | 1077 | A |
| 46 | Bend | 6407 | 4471 | 4647 | B |
| 47 | Bend | 3222 | 3107 | 3213 | D |
| 48 | Unincorporated | 3300 | 2968 | 3107 | E |
| 49 | Unincorporated | 638 | 525 | 651 | A |
| 50 | Unincorporated | 2087 | 1949 | 2025 | C |
| PRECINCT | Ballots_Cast_2024 | Reg_Voters_2024 | Total_Voters_2024 | Trump_Vance | Stine_Ware | Harris_Walz | Write.In |
|---|---|---|---|---|---|---|---|
| 1 | 2453 | 2890 | 2427 | 429 | 17 | 1910 | 16 |
| 2 | 3212 | 3952 | 3176 | 1234 | 12 | 1824 | 23 |
| 3 | 4041 | 4658 | 4013 | 675 | 37 | 3191 | 31 |
| 4 | 3198 | 3959 | 3180 | 770 | 22 | 2303 | 13 |
| 5 | 4434 | 5466 | 4391 | 1483 | 27 | 2731 | 34 |
| 6 | 2782 | 3846 | 2754 | 848 | 29 | 1802 | 10 |
| 7 | 1477 | 1677 | 1461 | 287 | 6 | 1139 | 6 |
| 8 | 835 | 954 | 819 | 256 | 3 | 534 | 12 |
| 9 | 1941 | 2780 | 1923 | 665 | 20 | 1180 | 13 |
| 10 | 36 | 61 | 36 | 31 | 0 | 5 | 0 |
| 11 | 1456 | 1762 | 1439 | 395 | 12 | 988 | 9 |
| 12 | 750 | 884 | 743 | 393 | 3 | 329 | 4 |
| 13 | 3060 | 3748 | 3035 | 1543 | 23 | 1388 | 14 |
| 14 | 1585 | 1911 | 1562 | 804 | 2 | 716 | 14 |
| 15 | 2368 | 2697 | 2352 | 1079 | 9 | 1190 | 29 |
| 16 | 1354 | 1555 | 1339 | 472 | 3 | 836 | 12 |
| 17 | 5991 | 8479 | 5942 | 3187 | 17 | 2507 | 51 |
| 18 | 3282 | 4075 | 3249 | 2224 | 9 | 947 | 10 |
| 19 | 1104 | 1487 | 1097 | 705 | 6 | 362 | 2 |
| 20 | 4759 | 5906 | 4715 | 1891 | 26 | 2643 | 37 |
| 21 | 2954 | 3582 | 2919 | 1653 | 20 | 1155 | 31 |
| 22 | 318 | 367 | 314 | 110 | 0 | 192 | 2 |
| 23 | 1428 | 2215 | 1422 | 903 | 6 | 468 | 9 |
| 24 | 931 | 1318 | 925 | 649 | 4 | 253 | 4 |
| 25 | 4238 | 5593 | 4207 | 1426 | 41 | 2597 | 26 |
| 26 | 2560 | 3114 | 2533 | 970 | 7 | 1478 | 16 |
| 27 | 2385 | 2860 | 2369 | 408 | 23 | 1872 | 10 |
| 28 | 3098 | 4182 | 3056 | 1690 | 23 | 1253 | 24 |
| 29 | 4770 | 6422 | 4717 | 2754 | 14 | 1806 | 30 |
| 30 | 2652 | 3174 | 2623 | 1014 | 17 | 1502 | 27 |
| 31 | 3029 | 3373 | 2997 | 1574 | 4 | 1347 | 31 |
| 32 | 2406 | 3352 | 2397 | 726 | 24 | 1587 | 5 |
| 33 | 3581 | 4228 | 3548 | 1439 | 13 | 2003 | 14 |
| 34 | 3221 | 4520 | 3188 | 1255 | 23 | 1813 | 16 |
| 35 | 4461 | 4982 | 4401 | 1103 | 8 | 3178 | 46 |
| 36 | 5488 | 7490 | 5442 | 2982 | 31 | 2243 | 37 |
| 37 | 1164 | 1384 | 1160 | 516 | 2 | 600 | 10 |
| 38 | 1454 | 1808 | 1441 | 623 | 7 | 760 | 13 |
| 39 | 5415 | 7172 | 5363 | 3042 | 18 | 2155 | 21 |
| 40 | 1179 | 1639 | 1174 | 772 | 2 | 377 | 3 |
| 41 | 666 | 772 | 660 | 322 | 3 | 316 | 4 |
| 42 | 3396 | 4512 | 3364 | 1771 | 21 | 1480 | 10 |
| 43 | 2732 | 3311 | 2709 | 1531 | 12 | 1093 | 17 |
| 44 | 3148 | 3971 | 3121 | 1184 | 12 | 1818 | 25 |
| 45 | 925 | 1085 | 912 | 361 | 1 | 523 | 7 |
| 46 | 3646 | 4604 | 3616 | 1116 | 38 | 2352 | 24 |
| 47 | 2829 | 3218 | 2790 | 732 | 9 | 1981 | 21 |
| 48 | 2419 | 3083 | 2396 | 1672 | 6 | 658 | 14 |
| 49 | 522 | 594 | 517 | 189 | 1 | 313 | 3 |
| 50 | 1453 | 2046 | 1441 | 992 | 5 | 410 | 4 |
Following the methods outlined here we used the Redist package in R statistical software to simulate 20,000 district plans. We followed the committee’s decision to use current voter registration as the population data. We use the 2024 presidential results to estimate partisan vote share because it is a recent high turn out election that used the current precinct map. We use a slightly simplified precinct map to meet the requirement for contiguous districts because the current county precinct map includes some non contiguous precincts.
Another way to look a the same data is to plot district plans based on the number of expected Democratic seats. A large majority of simulated district plans, 76.96% produce three seats that favor Democrats. Some plans, 15.5%, produce four districts that favor Democrats. Plans that have only two Democratic leaning seats were the least common representing only 7.53% of the simulated plans.
---
title: Analysis of partisan bias in DMAC proposed Deschutes County Commissioner Districts
author: "Bryce Kellogg"
date: "`r Sys.Date()`"
output:
flexdashboard::flex_dashboard:
source_code: embed
orientation: column
vertical_layout: scroll
---
```{r setup, include=FALSE}
library(flexdashboard)
```
```{r}
# load libraries needed for analysis
library(dplyr)
library(ggplot2)
library(redist)
library(sf)
# library for interactive viewing
library(mapview)
# libraries for working with census data
library(tidycensus)
library(tidyverse)
# libraries for data output
library(knitr)
library(plotly)
library(fromhere)
```
```{r, include=FALSE}
# load 2025 precincts that have been cleaned and simplified to be contiguous
# Original Data Downloaded Sep. 17th 2025, Deschutes County Data Portal https://data.deschutes.org/maps/c195adda97884f51822d5f884fa32179
Precincts2025<- st_read("data/Precinct_clean_contig_dissovle.shp")
# convert precinct to integer
Precincts2025$PRECINCT<-as.integer(Precincts2025$PRECINCT)
# Drop extra columns and arrange by Precinct so it plays nicely with redistr
Precincts2025 <- Precincts2025 %>%
select(-fid,-cat)%>%
arrange(PRECINCT)
# join the data from voter registration to the precinct
# Data from DMAC handout here https://www.deschutes.org/sites/default/files/fileattachments/board_of_county_commissioners/page/28588/dmac_meeting_packet_-_september_17_2025.pdf
#and proposed districts here https://www.deschutes.org/sites/default/files/fileattachments/board_of_county_commissioners/page/28588/map_c_with_data_graphs.pdf
Precinct_districts<- read_csv("data/Precinct_voter_district.csv")
Precincts2025 <- full_join(Precincts2025, Precinct_districts,by="PRECINCT")
```
```{r}
#load 2024 election results by precinct
# data available page 12-13 of canvass report here https://weblink.deschutes.org/Public/DocView.aspx?id=97755&dbid=0&repo=LFPUB
Election_2024<-read.csv("data/Pres_Elect_2024.csv")
#join to Precincts data frame
Precincts2025<-left_join(Precincts2025, Election_2024, by = "PRECINCT")
```
```{r}
#create a redistr map object using AUG 25 voter registration as population and 10 variance between highest and lowest districts
deschutes_map = redist_map(Precincts2025,ndists = 5,total_pop=Vote_Reg_2025, pop_tol=0.05)
#generate 20,000 random plans for 5 districts
deschutes_plans = redist_smc(deschutes_map, 10000, compactness=1, runs=2, verbose=T)
```
```{r}
# load DMAC proposed plan
#proposed districts here https://www.deschutes.org/sites/default/files/fileattachments/board_of_county_commissioners/page/28588/map_c_with_data_graphs.pdf
plan_c<-read.csv("data/PlanC.csv")
#add to simulated plans
deschutes_plans<-add_reference(deschutes_plans, plan_c$PLAN_C)
```
```{r}
#Find percent republican and democratic votes by district for each district
deschutes_plans = deschutes_plans %>%
mutate(pct_dem = group_frac(deschutes_map, Harris_Walz, Harris_Walz + Trump_Vance, deschutes_plans), pct_rep = group_frac(deschutes_map, Trump_Vance, Harris_Walz + Trump_Vance, deschutes_plans))
# another way to look at the same data is to look at how many democratic seats each plan is likely to produce.
D_seats<-as.data.frame(part_dseats(deschutes_plans, deschutes_map, dvote= Harris_Walz, rvote=Trump_Vance)%>%
by_plan())
names(D_seats)<-c("Number_d_seats")
#
summary_D_seats<-D_seats %>% count(`Number_d_seats`)
names(summary_D_seats)<-c("Number_d_seats", "Count")
summary_D_seats$precent<-summary_D_seats$Count/sum(summary_D_seats$Count)*100
```
Summary
========================
Column
-------------------------------------
### Intoduction
The Deschutes County Commission formed the District Mapping Advisory Committee (DMAC) to develop a plan for splitting the county into 5 commissioner districts. The resulting map called "Plan C" by the committee has been submitted to the county commission. You can view the map and partisan lean at the [Dave’s Redistricting website](https://davesredistricting.org/maps#viewmap::3d60de9b-5e0e-427f-b30a-1e89ac72483d)
County wide Democratic vote share in 2024 presidential election was `r round(sum(Election_2024$Harris_Walz)/sum(Election_2024$Total_Voters_2024)*100,digits = 2)`%. The plan proposed by the DMAC favors Republicans in 3 of the 5 districts. This discrepancy shows that the proposed map favors Republican candidates when compared to at large elections. But is the map gerrymandered? The partisan bias could be the natural result of geography and voter distribution across the county rather than intentional crafting.
To address this question we generate 20,000 district plans that follow requirements for population parity, continuity, and use of existing precinct boundaries. Simulating district plans allows for an apples to apples comparison with the DMAC’s proposed districts. We compare the Democratic vote share in the simulated districts to the DMAC proposed map. Partisan vote share is based on the results of the 2024 presidential election.
This comparison shows the partisan bias of the committees proposed districts is not an inevitable result of county geography. The DMAC proposal packs Democratic voters into two districts, leaving three districts that favor Republican candidates. Only around `r round(summary_D_seats$precent[summary_D_seats$Number_d_seats==2], digits = 0)`% of the simulated district plans produced 3 seats that favored Republicans.
The code and data used for this analysis is available here. https://drive.google.com/drive/folders/1sRVrttp4ZBPGu1qT6UXP9V1p6XSFUyYw?usp=share_link (link must be copied into browser)
Column
----------------
### DMAC Proposed Districts
```{r}
#view Proposed districts
mapview(Precincts2025, zcol = "OptionCDistrict")
```
Input data
==========
#### Source Data
[Original Precinct Data (Downloaded Sep. 17th 2025), Deschutes County Data Portal](https://data.deschutes.org/maps/c195adda97884f51822d5f884fa32179)
[Voter Registration and Census Population from DMAC handout](https://www.deschutes.org/sites/default/files/fileattachments/board_of_county_commissioners/page/28588/dmac_meeting_packet_-_september_17_2025.pdf)
[2024 Presidential Election Results pages 12 and 13 of canvass report](https://weblink.deschutes.org/Public/DocView.aspx?id=97755&dbid=0&repo=LFPUB)
[DMAC proposed districts](https://www.deschutes.org/sites/default/files/fileattachments/board_of_county_commissioners/page/28588/map_c_with_data_graphs.pdf)
#### Cleaned Data
Data formatted for analysis in r here https://drive.google.com/drive/folders/1sRVrttp4ZBPGu1qT6UXP9V1p6XSFUyYw?usp=share_link (link must be copied into browser)
```{r}
# voter registration by precinct
kable(Precinct_districts,caption = "Precinct, Voter Registration, Population, and DMAC Proposed District. source: DMAC handouts")
# 2024 election results by precinct
kable(Election_2024, caption = "2024 Presidential Election Results by Precinct. source: Canvass Reports")
```
Simulating District Plans
============
Column
-------------------------------------
### Adjacency plot of precincts used for district simulation
```{r}
#show adjacently graph for precincts
plot(deschutes_map, adj=TRUE)
```
### Five of the 20,000 randomly generated district plans
```{r}
#plot the first 5 random plans
redist.plot.plans(deschutes_plans, draws=1:5, shp=deschutes_map)
```
Column
--------
### Methods
Following the methods outlined [here](https://alarm-redist.org/redist/articles/redist.html) we used the Redist package in R statistical software to simulate 20,000 district plans. We followed the committee's decision to use current voter registration as the population data. We use the 2024 presidential results to estimate partisan vote share because it is a recent high turn out election that used the current precinct map. We use a slightly simplified precinct map to meet the requirement for contiguous districts because the current county precinct map includes some non contiguous precincts.
Results
=========
Column
-------------------------------------
###
```{r}
#Plot rain cloud plots comparing districts ordered percent democratic votes to the proposed districts.
library(ggrain)
rain_p<-plot(deschutes_plans, pct_dem, size=0.0,alpha = 0.0)+
geom_rain(
point.args.pos = rlang::list2(position = position_jitter(width = 0.05, height = 0),alpha=.01,size=.1),
boxplot.args.pos = list( width = 0.05, position = position_nudge(x = 0.13)),
violin.args.pos = list(side = "r", width = 0.7, position = position_nudge(x = 0.2)))+
xlab("Districts (Ordered by % Democratic Votes)")+
ylab("Proportion of Democratic Votes")
rain_p
```
### Partsian vote share by district
This plot show the percent of Democratic voters by district for each plan. The districts are sorted by percent of Democratic support, the district with the least Democratic voter base is show on the left for each plan and the district with the highest Democratic vote share is show on the right for each plan. The DMAC proposed districts are represented by a red lines. Each point represents one simulated district. The box plot and density plots show the distribution of simulated districts.
The partisan nature of the DMAC proposed districts revealed by the mismatch between their proposal and the simulated districts. The two Democratic districts proposed by DMAC have a much higher proportion of Democratic voters than the most of the simulated plans. This shows the packing of Democratic voters into two districts. The most competitive district proposed by DMAC, district 3 in the plot, also falls well outside the expectations from simulated districts. The packing of Democratic voters into two districts allows for a 3rd Republican district to be drawn. Overall the plot shows that there are many way to draw districts that would be more inline with the county wide vote share.
Column
-----------------
###
```{r}
# another way to look at the same data is to look at how many democratic seats each plan is likely to produce.
D_seats<-as.data.frame(part_dseats(deschutes_plans, deschutes_map, dvote= Harris_Walz, rvote=Trump_Vance)%>%
by_plan())
names(D_seats)<-c("Number_d_seats")
#
summary_D_seats<-D_seats %>% count(`Number_d_seats`)
names(summary_D_seats)<-c("Number_d_seats", "Count")
summary_D_seats$precent<-summary_D_seats$Count/sum(summary_D_seats$Count)*100
D_seat_plot<-ggplot(D_seats,aes(`Number_d_seats`))+
geom_histogram(binwidth = 1, fill="#69b3a2", color="#e9ecef", alpha=0.9)+theme_minimal()+
xlab("# of Likely Democratic seats")+
ggtitle("Number of Likely Democratic Seats for each Simualted Plan")
ggplotly(D_seat_plot)
```
### Likley Number of Democratic Seats
Another way to look a the same data is to plot district plans based on the number of expected Democratic seats. A large majority of simulated district plans, `r round(summary_D_seats$precent[summary_D_seats$Number_d_seats==3],digits=2)`% produce three seats that favor Democrats. Some plans, `r round(summary_D_seats$precent[summary_D_seats$Number_d_seats==4],digits = 2)`%, produce four districts that favor Democrats. Plans that have only two Democratic leaning seats were the least common representing only `r round(summary_D_seats$precent[summary_D_seats$Number_d_seats==2], digits = 2)`% of the simulated plans.