library(targets)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ readr 2.1.5
✔ forcats 1.0.0 ✔ stringr 1.5.1
✔ ggplot2 3.5.1 ✔ tibble 3.2.1
✔ lubridate 1.9.4 ✔ tidyr 1.3.1
✔ purrr 1.0.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
tar_load(cvr_long_appended)
First round CVR counts
cvr_long_appended |>
filter(office == "DEM Mayor") |>
filter(rank == min(rank), .by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Zohran Kwame Mamdani |
469,642 |
Andrew M. Cuomo |
387,137 |
Brad Lander |
120,634 |
Adrienne E. Adams |
44,192 |
Scott M. Stringer |
17,820 |
Zellnor Myrie |
10,593 |
Whitney R. Tilson |
8,443 |
overvote |
5,500 |
Michael Blake |
4,366 |
Jessica Ramos |
4,273 |
Write-in |
1,581 |
Paperboy Love Prince |
1,560 |
Selma K. Bartholomew |
1,489 |
This matches the candidate counts reported in the first round exactly!
Second round CVR counts: Removing write-in top choices
cvr_long_appended |>
filter(office == "DEM Mayor",
DefaultBallotName != "Write-in") |>
filter(rank == min(rank),
.by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Zohran Kwame Mamdani |
469,755 |
Andrew M. Cuomo |
387,377 |
Brad Lander |
120,707 |
Adrienne E. Adams |
44,359 |
Scott M. Stringer |
17,894 |
Zellnor Myrie |
10,648 |
Whitney R. Tilson |
8,525 |
overvote |
5,506 |
Michael Blake |
4,389 |
Jessica Ramos |
4,294 |
Paperboy Love Prince |
1,628 |
Selma K. Bartholomew |
1,505 |
Third round CVR counts
cvr_long_appended |>
filter(office == "DEM Mayor",
DefaultBallotName %in% c("Zohran Kwame Mamdani",
"Andrew M. Cuomo")) |>
filter(rank == min(rank),
.by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Zohran Kwame Mamdani |
573,635 |
Andrew M. Cuomo |
443,762 |
Cuomo vs. Lander
cvr_long_appended |>
filter(office == "DEM Mayor",
DefaultBallotName %in% c("Brad Lander",
"Andrew M. Cuomo")) |>
filter(rank == min(rank),
.by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Brad Lander |
527,418 |
Andrew M. Cuomo |
441,760 |
Cuomo vs. Adams
cvr_long_appended |>
filter(office == "DEM Mayor",
DefaultBallotName %in% c("Adrienne E. Adams",
"Andrew M. Cuomo")) |>
filter(rank == min(rank),
.by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Adrienne E. Adams |
457,755 |
Andrew M. Cuomo |
451,439 |
Adams vs. Mamdani
cvr_long_appended |>
filter(office == "DEM Mayor",
DefaultBallotName %in% c("Adrienne E. Adams",
"Zohran Kwame Mamdani")) |>
filter(rank == min(rank),
.by = c(fn, `Cast Vote Record`)) |>
#filter(!is.na(candidate)) |>
count(DefaultBallotName) |>
arrange(desc(n)) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::cols_label("DefaultBallotName" = "Candidate",
"n" = "Votes")
Zohran Kwame Mamdani |
582,746 |
Adrienne E. Adams |
196,728 |
Common 2nd and 3rd rankings for voters ranking various candidates first
cvr_long_appended |>
filter(office == "DEM Mayor",
rank %in% 1:3) |>
mutate(cand = str_extract(DefaultBallotName, "\\b(\\w+)$")) |>
summarize(first_choice = cand[rank==1][1],
ranking = paste0(sort_by(cand[rank>1],
rank[rank>1]),
collapse = "|"),
.by = c(fn, `Cast Vote Record`)) |>
count(first_choice, ranking) |>
mutate(ranking = if_else(ranking == "", "(None ranked)", ranking)) |>
arrange(first_choice, desc(n)) |>
mutate(cumpct = cumsum(n)/sum(n),
.by = first_choice) |>
slice(1:10, .by = first_choice) |>
filter(first_choice %in% c("Cuomo", "Mamdani", "Lander", "Adams")) |>
group_by(first_choice) |>
gt::gt() |>
gt::fmt_number(decimals = 0) |>
gt::fmt_percent(4, decimals = 0) |>
gt::cols_label("n" = "No. of Ballots",
"first_choice" = "First Choice",
"ranking" = "Next two choices",
"cumpct" = "Cumulative precent") |>
gt::tab_style(
style = gt::cell_text(weight = "bold", color = "darkblue"),
locations = gt::cells_row_groups(groups = everything())
)
Adams |
(None ranked) |
6,457 |
15% |
Mamdani|Lander |
2,633 |
21% |
Lander|Mamdani |
2,568 |
27% |
Lander|Stringer |
2,456 |
32% |
Cuomo |
2,243 |
37% |
Lander|Myrie |
1,445 |
41% |
Cuomo|Stringer |
1,294 |
43% |
Mamdani|Myrie |
1,239 |
46% |
Stringer|Lander |
1,238 |
49% |
Cuomo|Lander |
1,235 |
52% |
Cuomo |
(None ranked) |
163,936 |
43% |
Lander|Stringer |
12,435 |
46% |
Adams |
11,446 |
49% |
Cuomo|Cuomo |
10,753 |
52% |
Stringer|Lander |
10,215 |
54% |
Myrie|Adams |
9,566 |
57% |
Tilson |
9,411 |
59% |
Stringer |
9,244 |
61% |
Lander |
8,536 |
64% |
Tilson|Stringer |
8,262 |
66% |
Lander |
Mamdani|Adams |
21,643 |
18% |
Mamdani|Myrie |
9,333 |
26% |
Adams|Mamdani |
6,562 |
31% |
Adams|Stringer |
6,487 |
37% |
Mamdani|Stringer |
6,346 |
42% |
Adams|Myrie |
5,669 |
46% |
Stringer|Adams |
5,612 |
51% |
Mamdani |
4,412 |
55% |
(None ranked) |
4,132 |
58% |
Myrie|Adams |
3,771 |
61% |
Mamdani |
Lander|Adams |
168,064 |
36% |
Lander|Myrie |
48,038 |
46% |
(None ranked) |
39,101 |
54% |
Lander|Blake |
33,764 |
62% |
Adams|Lander |
23,599 |
67% |
Lander |
18,982 |
71% |
Lander|Stringer |
18,217 |
75% |
Lander|Ramos |
10,120 |
77% |
Blake|Lander |
4,779 |
78% |
Cuomo |
4,495 |
79% |