
Seat Allocation Explained
Source:vignettes/articles/seat-allocation-explained.rmd
seat-allocation-explained.rmd
To determine the order in which seats are allocated to parties, the
NZ
Electoral Commission follows the below process.
Step 1: Tally Party Votes
First, all Party Votes are tallied for each party and the number of electorate seats won are also tallied.
# load dataset
df <- scgUtils::get_data("summary")
df <- df %>%
# filter out total ballot type, leaving the candidate and party ballor
# types only
filter(Ballot != "Total",
# filter for the most recent election
Election == 2023) %>%
# keep party votes only by removing candidate votes
mutate(Votes = ifelse(Ballot == "Candidate", 0, Votes),
# NB % is not required in this step and is only included
# for illustrative purposes
Percentage = ifelse(Ballot == "Candidate", 0, Percentage),
# keep the number of electorate seats only by removing
# party/list seats
Seats = ifelse(Ballot == "Party", 0, Seats)) %>%
# group long format data frame (NB keep 'Successful' column)
group_by(Party, Successful) %>%
summarise(Votes = sum(Votes), Percentage = sum(Percentage),
Seats = sum(Seats), .groups = 'drop') %>%
ungroup() %>%
arrange(-Votes)
head(df)
#> # A tibble: 6 × 5
#> Party Successful Votes Percentage Seats
#> <chr> <chr> <dbl> <dbl> <dbl>
#> 1 National Party Yes 1085851 38.1 43
#> 2 Labour Party Yes 767540 26.9 17
#> 3 Green Party Yes 330907 11.6 3
#> 4 ACT Party Yes 246473 8.64 2
#> 5 NZ First Yes 173553 6.09 0
#> 6 Maori Party Yes 87844 3.08 6
Step 2: Determine Seat Entitlement
Next, ineligible parties (those which do not achieve above 5% Party Vote or win at least 1 electorate) are removed from the denominator of the total votes. The percentage of all party votes is recalculated and the seat entitlement and number of top-up seats are determined.
df <- df %>%
# filer out ineligible parties
filter(Successful == "Yes") %>%
# New percentage
mutate(Percentage = Votes/sum(Votes)*100,
# Number of seats each party is entitled to
Entitlement = round(120 * Percentage/100, digits=0),
# Number of top-up seats
Top_Up = Entitlement - Seats)
head(df)
#> # A tibble: 6 × 7
#> Party Successful Votes Percentage Seats Entitlement Top_Up
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 National Party Yes 1085851 40.3 43 48 5
#> 2 Labour Party Yes 767540 28.5 17 34 17
#> 3 Green Party Yes 330907 12.3 3 15 12
#> 4 ACT Party Yes 246473 9.16 2 11 9
#> 5 NZ First Yes 173553 6.45 0 8 8
#> 6 Maori Party Yes 87844 3.26 6 4 -2
Step 3: Use Saint-Laguë Formula
Next, the Sainte-Laguë formula, \(Quotient = \frac{Votes}{(2s + 1)}\), is used to determine the order of seats.
NB \(s\) begins at 0 for each Party and increases by 1 as seats are allocated each round. This means that the total number of \(Votes\) for each party is divided by an odd number every round.
i.e.,
- \((2 \times 0 + 1) = 1\)
- \((2 \times 1 + 1) = 3\)
- \((2 \times 2 + 1) = 5\)
and so on…
n <- 120 # Total number of seats:
df1 <- data.frame()
# s begins at 0 and sequences up until total number of seats
# has been reached
for(s in seq(0,n)) {
tmp <- df %>%
# Saint-Lague Formula:
mutate(Quotient = Votes / (2*s + 1),
# included for illustrative purposes only
s = s) %>%
select(Party, Quotient, s)
df1 <- rbind(df1, tmp)
}
head(df1,10)
#> # A tibble: 10 × 3
#> Party Quotient s
#> <chr> <dbl> <int>
#> 1 National Party 1085851 0
#> 2 Labour Party 767540 0
#> 3 Green Party 330907 0
#> 4 ACT Party 246473 0
#> 5 NZ First 173553 0
#> 6 Maori Party 87844 0
#> 7 National Party 361950. 1
#> 8 Labour Party 255847. 1
#> 9 Green Party 110302. 1
#> 10 ACT Party 82158. 1
Step 4: Determine Allocation Order
Each seat is then allocated to a party based on the order of the \(Quotient\) from highest to lowest. This continues until all 120 seats are allocated (NB this disregards any overhang seats given that these come from excess electorate seats and not list seats).
# Order seats by Quotient (highest to lowest) and subset
# rows by the total number of seats (120):
df1 <- df1[order(-df1$Quotient),]
df1 <- df1[1:n,]
# Allocate seat number:
df1$Allocation <- 1:n
head(df1,10)
#> # A tibble: 10 × 4
#> Party Quotient s Allocation
#> <chr> <dbl> <int> <int>
#> 1 National Party 1085851 0 1
#> 2 Labour Party 767540 0 2
#> 3 National Party 361950. 1 3
#> 4 Green Party 330907 0 4
#> 5 Labour Party 255847. 1 5
#> 6 ACT Party 246473 0 6
#> 7 National Party 217170. 2 7
#> 8 NZ First 173553 0 8
#> 9 National Party 155122. 3 9
#> 10 Labour Party 153508 2 10