Learn R Programming

vote (version 2.0-1)

stv: Single Transferable Vote

Description

Count votes using the single transferable voting method, also known as ranked choice voting or instant runoff.

Usage

stv(votes, mcan = NULL, eps = 0.001, equal.ranking = FALSE, 
  fsep = '\t', verbose = FALSE, seed = 1234, quiet = FALSE, …)

# S3 method for vote.stv summary(object, …, digits = 3)

# S3 method for vote.stv view(object, …)

# S3 method for vote.stv plot(x, xlab = "Count", ylab = "Preferences", point.size = 2, …)

# S3 method for vote.stv image(x, xpref = 2, ypref = 1, all.pref = FALSE, proportion = TRUE, …)

correct.ranking(votes, quiet = FALSE)

Arguments

votes

Matrix or data frame containing the votes. Rows correspond to the votes, columns correspond to the candidates. If it is a character string it is interpreted as a file name from which the votes are to be read. See below for more details.

mcan

Number of candidates to be elected. By default it is half the number of candidates standing.

eps

Value added to the quota. I.e. the STV quota is computed as number_of_first_preferences/(number_of_seats + 1) + eps.

equal.ranking

If TRUE equal preferences are allowed, see below.

fsep

If votes is a file name, this argument gives the column separator in the file.

verbose

Logical. If TRUE the progress of the count will be printed.

seed

Integer. Seed of the random number generator. Only used if there are ties that cannot be resolved by the tie-breaking method. If set to NULL, the RNG is not initialized.

quiet

If TRUE no output is printed.

object, x

Object of class vote.stv.

digits

How many significant digits to be used in the output table.

xlab, ylab

Labels of the x- and y-axis.

point.size

Size of the points in the plot.

xpref, ypref

Preference for the x- and y-axis, respectively, for showing the joined distribution of the votes. It is not used if all.pref is TRUE.

all.pref

Logical. If TRUE the marginal distribution of all preferences is shown in the image. Otherwise, the joint distribution of xpref and ypref is shown.

proportion

If TRUE the preferences are shown as proportions across the x-axis, otherwise raw vote counts are shown. Only available when all.pref is FALSE.

Additional arguments passed to the underlying functions.

Value

Function stv returns an object of class vote.stv which is a list with the following objects:

elected

Vector of names of the elected candidates in the order in which they were elected.

preferences

Matrix of preferences. Columns correspond to the candidates and rows to the counts (i.e. voting rounds).

quotas

Vector of quotas, one for each count.

elect.elim

Matrix of the same shape as preferences. Value 1 means that the corresponding candidate was elected in that round; value -1 means an elimination.

equal.pref.allowed

Input argument equal.ranking.

data

Input data (possibly corrected) with invalid votes removed.

invalid.votes

Matrix of invalid votes that were removed from the original dataset.

Details

For a description of the single transferable vote system see https://imstat.org/elections/single-transferable-voting-system/.

The input data votes is structured as follows: Row \(i\) contains the preferences of voter \(i\) numbered \(1, 2, \dots, r, 0,0,0,0\), in some order. The columns correspond to the candidates. The dimnames of the columns are the names of the candidates; if these are not supplied then the candidates are lettered A, B, C, …. If the dataset contains missing values (NA), they are replaced by zeros.

By default the preferences are not allowed to contain duplicates per vote. However, if the argument equal.ranking is set to TRUE, votes are allowed to have the same ranking for multiple candidates. The desired format is such that for each preference \(i\) that does not have any duplicate, there must be exactly \(i-1\) preferences \(j\) with \(0 < j < i\). For example, valid ordered preferences are \(1,1,3,4,\dots\), or \(1,2,3,3,3,6,\dots\), but NOT \(1,1,2,3,\dots\), or NOT \(1,2,3,3,3,5,6,\dots\). If the data contain such invalid votes, they are automatically corrected and a warning is issued by calling the correct.ranking function.

The correct.ranking function does the above correction for all records, regardless if they contain duplicates or not. It can either be used by calling it explicitely, otherwise it is called by stv if equal.ranking = TRUE. The function is also called from within the condorcet function.

Ties in the STV algorithm are resolved using the forwards tie-breaking method, see Newland and Briton (Section 5.2.5).

The plot function shows the evolution of the total score for each candidate as well as the quota. The image function visualizes the joint distribution of two preferences (if all.pref=FALSE) as well as the marginal distribution of all preferences (if all.pref=TRUE). The joint distribution can be shown either as proportions (if proportion=TRUE) or raw vote counts (if proportion=FALSE).

References

R.A. Newland and F.S. Britton (1997). How to conduct an election by the Single Transferable Vote. ERS 3rd Edition. http://www.rosenstiel.co.uk/stvrules/index.html

https://imstat.org/elections/single-transferable-voting-system/

https://en.wikipedia.org/wiki/Single_transferable_vote

Examples

Run this code
# NOT RUN {
# Reproducing example from Wikipedia
# https://en.wikipedia.org/wiki/Single_transferable_vote#Example
# Uses eps=1
data(food_election)
stv.food <- stv(food_election, mcan = 3, eps = 1)
summary(stv.food)
# }
# NOT RUN {
view(stv.food)
# }
# NOT RUN {
# Example of the IMS Council voting
data(ims_election)
stv.ims <- stv(ims_election, mcan = 5)
# }
# NOT RUN {
view(stv.ims)
plot(stv.ims)
image(stv.ims)

# write election results into a csv file
s <- summary(stv.ims)
write.csv(s, "myfile.csv")
# }
# NOT RUN {
# }
# NOT RUN {
# Example of Dublin West 2002 elections
# https://en.wikipedia.org/wiki/Dublin_West#2002_general_election
data(dublin_west)
stv(dublin_west, mcan = 3, eps = 1)
# }
# NOT RUN {
# Example of a small committee dataset
# with four candidates (C) and four
# voting committee members (uses tie-breaking)
votes <- data.frame(C1=c(3,2,1,3), C2=c(2,1,2,4),
                    C3=c(4,3,3,1), C4=c(1,4,4,2))
stv(votes, mcan = 2, verbose = TRUE)

# Example with equal ranking and correction
votes <- data.frame(C1=c(3,2,1,3), C2=c(1,1,2,0),
                    C3=c(4,3,3,1), C4=c(1,4,2,2))
stv(votes, mcan = 2, equal.ranking = TRUE)
# vote #3 was corrected by stv which used this data:
correct.ranking(votes, quiet = TRUE)
# }

Run the code above in your browser using DataLab