Categories
Election Data Analysis Election Forensics Election Integrity Interesting programming technical

Computing the VA 2020 Daily Absentee Ballot List Rejection Rate and Other Stats

Adding onto the work I’ve already done looking at the VA Daily Absentee List I wanted to compute the rejection rate for absentee ballots and some other basic statistics just from the Daily Absentee Ballot List (DAL) produced by VA Dept of Elections. (https://www.elections.virginia.gov/candidatepac-info/client-services/)

Keep in mind I’ve already been able to show:

  • There were 166 Absentee Ballot Applications that were received and accepted AFTER the corresponding ballot was received or accepted (here).
  • There is a discrepancy in the number of “excess” absentee votes counted vs. the total accepted registrations from the Daily Absentee List (here).
  • The 2020 VA election fingerprints, as well as other states, have significant structural irregularities and indications of vote manipulation (here).
  • The VA election fingerprints show a trend of increasing irregularity starting with 2008, 2012, 2016 and now 2020 (here).

Basic Info:

There are 3335335 entries, with 36 columns in the Daily Absentee List.

The column headings are: ELECTION_NAME, LOCALITY_CODE, LOCALITY_NAME, PRECINCT_CODE, PRECINCT_NAME, LAST_NAME, FIRST_NAME, MIDDLE_NAME, SUFFIX, ADDRESS_LINE_1, ADDRESS_LINE_2, ADDRESS_LINE_3, CITY, STATE, ZIP, COUNTRY, INTERNATIONAL, EMAIL_ADDRESS, FAX, VOTER_TYPE, ONGOING, APP_RECIEPT_DATE, APP_STATUS, BALLOT_RECEIPT_DATE, BALLOT_STATUS, identification_number, PROTECTED, CONG_CODE_VALUE, STSENATE_CODE_VALUE, STHOUSE_CODE_VALUE, AB_ADDRESS_LINE_1, AB_ADDRESS_LINE_2, AB_ADDRESS_LINE_3, AB_CITY, AB_STATE, AB_ZIP

Computing the Absentee Ballot Rejection Rate:

So (in MATLAB), with the full list directly imported into the ‘DailyAbsenteeList’ table variable:

% Lets see if we can teas out the rejection rate for 
% absentee ballots
>> ineligable = DailyAbsenteeList.APP_STATUS == "Denied/Not Eligible";
>> incomplete = DailyAbsenteeList.APP_STATUS == "Denied/Incomplete";
>> rejectionRate = 100 * mean(ineligable | incomplete)
>> ans = 0.0425

RESULT: The absentee ballot rejection rate was an exceptionally low 0.0425%

Finding the Counted ballots:

As we did in the “excess vote” computation, we need to find the indices into the list of all of the ballots that were counted, meaning their BALLOT_STATUS is in one of the following states: {‘On Machine’, ‘Marked’, ‘Pre-Processed’, ‘FWAB’}. So the ‘idxv’ variable below is a boolean flag indicating that the BALLOT_STATUS of each entry in the list is in a countable state.

% For each entry in the Daily Absentee List, test if 
% BALLOT_STATUS is in a valid state 
>> idxv = DailyAbsenteeList.BALLOT_STATUS=='Marked' | ...
    DailyAbsenteeList.BALLOT_STATUS=='Pre-Processed' | ...
    DailyAbsenteeList.BALLOT_STATUS=='On Machine' | ...
    DailyAbsenteeList.BALLOT_STATUS=='FWAB';

Now one would think that if a ballot has been marked into one of those BALLOT_STATUS categories, then that ballot application should have been ‘Approved’, right? Well lets double check that shall we:

% For each entry in the Daily Absentee List, test if 
% BALLOT_STATUS is in a valid state AND APP_STATUS is set to 
% 'Approved'.  (One would think these would match.)
>> idxav = (DailyAbsenteeList.BALLOT_STATUS=='Marked' | ...
    DailyAbsenteeList.BALLOT_STATUS=='Pre-Processed' | ...
    DailyAbsenteeList.BALLOT_STATUS=='On Machine' | ...
    DailyAbsenteeList.BALLOT_STATUS=='FWAB') & ...
    DailyAbsenteeList.APP_STATUS=='Approved';

We can check for mismatches by counting the number of flags that are not equal between ‘idxv’ and ‘idxav’.

% How many absentee ballots have their BALLOT_STATUS set to 
% a valid (i.e. "countable") state, but are not marked as 
% 'Approved'
>> numUnapprovedButCountableVotes = sum(idxv)-sum(idxav)
>> ans = 1437

RESULT: There are 1437 entries that have BALLOT_STATUS set to a valid state, but don’t have an approved absentee ballot application

Well … this begs some follow up questions…

Q1: Of the ballots that have been set to a valid BALLOT_STATUS state but were not set to ‘Approved’, what is the breakdown by APP_STATUS?

>> cancelled = sum(DailyAbsenteeList.APP_STATUS=='Cancelled or Duplicate' & (idxv~=idxav))
>> deniedInc = sum(DailyAbsenteeList.APP_STATUS=='Denied/Incomplete' & (idxv~=idxav))
>> deniedIne = sum(DailyAbsenteeList.APP_STATUS=='Denied/Not Eligible' & (idxv~=idxav))
>> issued = sum(DailyAbsenteeList.APP_STATUS=='Issued' & (idxv~=idxav))
>> onHold = sum(DailyAbsenteeList.APP_STATUS=='On Hold' & (idxv~=idxav))
>> pending = sum(DailyAbsenteeList.APP_STATUS=='Pending Approval' & (idxv~=idxav))
>> provisional = sum(DailyAbsenteeList.APP_STATUS=='Provisional' & (idxv~=idxav))

RESULTS: Of the 1437 ballots that were in a countable state but not marked as having APP_STATUS=’Accepted’, their APP_STATUS was:
cancelled = 444
deniedInc = 568
deniedIne = 4
issued = 28
onHold = 101
pending = 288
provisional = 4

Q2: Of the ballots that have been set to a valid BALLOT_STATUS state but were not set to ‘Approved’, what is the breakdown by BALLOT_STATUS?

>> unapproved_mailIn = sum(DailyAbsenteeList.BALLOT_STATUS=='Marked' & ...
    DailyAbsenteeList.APP_STATUS~='Approved')
>> unapproved_preProcessed = sum(DailyAbsenteeList.BALLOT_STATUS=='Pre-Processed' & ...
    DailyAbsenteeList.APP_STATUS~='Approved')
>> unapproved_earlyInPerson = sum(DailyAbsenteeList.BALLOT_STATUS=='On Machine' & ...
    DailyAbsenteeList.APP_STATUS~='Approved')
>> unapproved_FWAB = sum(DailyAbsenteeList.BALLOT_STATUS=='FWAB' & ...
    DailyAbsenteeList.APP_STATUS~='Approved')

RESULTS: Of the 1437 ballots that were in a countable state but not marked as having APP_STATUS=’Accepted’, their BALLOT_STATUS was:
unapproved_MailIn (‘Marked’) = 512
unapproved_preProcessed (‘Pre-Processed’) = 578
unapproved_earlyInPerson (‘On Machine’) = 347
unapproved_FWAB (‘FWAB’) = 0

Checking for duplicate identities:

Another check we can do is try to determine the amount of duplicated voters that have been accepted.

% What about the possibility of the same person being marked 
% with multiple ballots?  We will now go through 
% the'Accepted' and countable ballots and
% look for duplicate names and address information.
>> idxvs = find(idxav);
>> fnames = cellstr(DailyAbsenteeList.FIRST_NAME(idxvs));
>> lnames = cellstr(DailyAbsenteeList.LAST_NAME(idxvs));
>> mnames = cellstr(DailyAbsenteeList.MIDDLE_NAME(idxvs));
>> sffx = cellstr(DailyAbsenteeList.SUFFIX(idxvs));
>> addy1 = cellstr(DailyAbsenteeList.ADDRESS_LINE_1(idxvs));
>> addy2 = cellstr(num2str(DailyAbsenteeList.ADDRESS_LINE_2(idxvs)));
>> addy3 = cellstr(num2str(DailyAbsenteeList.ADDRESS_LINE_3(idxvs)));
>> zips = cellstr(num2str(DailyAbsenteeList.ZIP(idxvs)));
>> addy2 = strrep(strrep(addy2,'NaN',''),' ','');
>> addy3 = strrep(strrep(addy3,'NaN',''),' ','');
>> zips = strrep(strrep(zips,'NaN',''),' ','');
>> namesAndAddys = join([fnames, mnames, lnames, sffx, addy1, addy2, addy3, zips]);
>> [unames,unr,uni] = unique(namesAndAddys);
>> duplicateVotes = numel(namesAndAddys) - numel(unames)
>> ans = 166

RESULT: The number of repeated accepted absentee ballots is 166 … now where have we seen that number pop up before … ahhhh yes … its the same number of ballots that have ballot applications that we received and accepted AFTER the actual ballot was accepted and cast!