MIvoter: Manual Entry of County Election Data
Charles Roth
Last update: 1/6/2026
I. Introduction and Purpose
The primary goal of MIvoter.org is to encourage more people to vote for Democratically-endorsed candidates
(especially in "non-partisan" elections).
Secondarily, we provide contact & other information about all of
each voter's elected officials -- from top to bottom, Governor to (metaphorical) dog-catcher.
There is no central database of all elected officials in Michigan.
So -- we're building it!
In order to do this, we are "scraping" the data from each county's election results site(s).
Most of this is automated; we have a small pool of volunteers writing software to parse and import
the (many different formats of) county election data.
However... (and this is the part where you come in) some of these reports are (a) difficult to
automatically parse, and (b) very small.
Such as an odd-numbered year election that had a single contest.
In these cases, we're looking for a few volunteers to
manually enter the data.
II. The data we want
We are gathering the data for each general (November) election,
for the years 2020 - 2025,
for each county. For each contest (aka race), we want to end up
with a spreadsheet that looks like the below.
(The fields are actually separated by tab characters -- the 'tab' key on your keyboard,
shown here as 'large' spaces.)
yyyy-mm-dd county# title voteFor# candidateName partyName #votes
where
- yyyy-mm-dd is the date of the election
- county# is the county number. (See table below)
- title is the name of the office
- voteFor# is the number of people on the ballot that a voter should vote for
(often just 1, but for some races, e.g. board of education, it may be several)
- candidateName is the full name of the candidate
- partyName any form of the party name, e.g. Democratic, D, DEM, Non-partisan, Write-in, whatever.
- #votes the number of votes that candidate got.
Notes:
- We want only candidate races.
We ignore proposals, referenda, etc.
- We want only county-level offices or lower (cities, townships, villages, school boards).
We ignore state offices, including state house and senate (we already have that data from a single source).
- If there were 3 candidates in a contest, we want the data for all 3, not just the winner.
- A "tab-separated spreadsheet" is sometimes known as "CSV" or "TSV".
You can use any spreadsheet tool (Excel, OpenOffice, etc.), and just tell
it to save the file as a CSV or TSV, with tabs as the separator (not commas).
Or you can even use a simple text editor, like Notepad, and just type in the data,
separated by tabs (the tab key).
III. The data we have
Here's an example of a small-but-hard-to-parse election report:
Alger County Nov 7, 2023.
The relevant part looks like this:
The data that we want would look like this (Alger is county #2):
#yyyy-mm-dd county# title voteFor# candidateName partyName #votes
2023-11-07 2 City Commissioner for City of Munising 1 Jordan S. Prunic ? 200
The first line shows the field or column names, and the "#" at the start means this is a 'comment' line, which
will be ignored by our software.
The second line is the actual data.
(When you save the data as a CSV/TSV file, the fields are separated by the 'tab' character.)
That's it! This contest has only 1 person, but if there were more, each candidate would
get their own row.
You can download a template spreadsheet, that
has (just) the first comment line with the field names, and use that to start with.
The end result: save it in a CSV/TSV file.
Please give the file a very specific name, that includes the county name and the year,
e.g. alger-2023.
(Please don't put spaces in the filename.)
Then send it to wchasroth@gmail.com.
The files that we need to manually enter are listed at
manual-list.
If you do any of these files, please let us know at the above email address, ASAP, so
that no-one duplicates your work.
The list will be updated as we go, and more counties will probably be added.
IV. County Numbers
| 1 | ALCONA | 29 | GRATIOT | 57 | MISSAUKEE |
| 2 | ALGER | 30 | HILLSDALE | 58 | MONROE |
| 3 | ALLEGAN | 31 | HOUGHTON | 59 | MONTCALM |
| 4 | ALPENA | 32 | HURON | 60 | MONTMORENCY |
| 5 | ANTRIM | 33 | INGHAM | 61 | MUSKEGON |
| 6 | ARENAC | 34 | IONIA | 62 | NEWAYGO |
| 7 | BARAGA | 35 | IOSCO | 63 | OAKLAND |
| 8 | BARRY | 36 | IRON | 64 | OCEANA |
| 9 | BAY | 37 | ISABELLA | 65 | OGEMAW |
| 10 | BENZIE | 38 | JACKSON | 66 | ONTONAGON |
| 11 | BERRIEN | 39 | KALAMAZOO | 67 | OSCEOLA |
| 12 | BRANCH | 40 | KALKASKA | 68 | OSCODA |
| 13 | CALHOUN | 41 | KENT | 69 | OTSEGO |
| 14 | CASS | 42 | KEWEENAW | 70 | OTTAWA |
| 15 | CHARLEVOIX | 43 | LAKE | 71 | PRESQUE ISLE |
| 16 | CHEBOYGAN | 44 | LAPEER | 72 | ROSCOMMON |
| 17 | CHIPPEWA | 45 | LEELANAU | 73 | SAGINAW |
| 18 | CLARE | 46 | LENAWEE | 74 | ST CLAIR |
| 19 | CLINTON | 47 | LIVINGSTON | 75 | ST JOSEPH |
| 20 | CRAWFORD | 48 | LUCE | 76 | SANILAC |
| 21 | DELTA | 49 | MACKINAC | 77 | SCHOOLCRAFT |
| 22 | DICKINSON | 50 | MACOMB | 78 | SHIAWASSEE |
| 23 | EATON | 51 | MANISTEE | 79 | TUSCOLA |
| 24 | EMMET | 52 | MARQUETTE | 80 | VAN BUREN |
| 25 | GENESEE | 53 | MASON | 81 | WASHTENAW |
| 26 | GLADWIN | 54 | MECOSTA | 82 | WAYNE |
| 27 | GOGEBIC | 55 | MENOMINEE | 83 | WEXFORD |
| 28 | GRAND TRAVERSE | 56 | MIDLAND |