Count preferential ballots using an STV method
stv.Rd
The votes
parameter is as described in condorcet()
with the following additional semantics.
Usage
stv(
votes,
nseats = NULL,
eps = 0.001,
equal.ranking = FALSE,
fsep = "\t",
ties = c("f", "b"),
quota.hare = FALSE,
constant.quota = FALSE,
win.by.elim = TRUE,
group.nseats = NULL,
group.members = NULL,
complete.ranking = FALSE,
invalid.partial = FALSE,
verbose = FALSE,
seed = NULL,
quiet = FALSE,
digits = 3,
backwards.compatible = FALSE,
safety = 1,
...
)
Arguments
- votes
an array with one column per candidate and one row per ballot, as described in
condorcet()
- nseats
the number of seats to be filled in this election
- eps
fuzz-factor when comparing fractional votes. The default of 0.001 is preserved from the legacy code, injecting substantial validity hazards into the codebase. We have not attempted to mitigate any of these hazards in
SafeVote v1.0.0
. We prefer instead to retain backwards-compatibility with the legacy code invote_2.3-2
in the knowledge that, even if these hazards were adequately addressed, the resulting code is unlikely to be reliable at replicating the results of any other implementation of any of the many variants of "STV" counting methods. Please see the description of thea53_hil
dataset in this package for some preliminary findings on the magnitude of the vote-count-variances which may be injected by differing implementations of broadly-similar "STV" counting methods.- equal.ranking
if
TRUE
, equal preferences are allowed.- fsep
column-separator for output
- ties
vector of tie-breaking methods:
'f'
for forward,'b'
for backward- quota.hare
TRUE
if Hare quota,FALSE
if Droop quota (default)- constant.quota
TRUE
if quota is held constant. Over-ridesquota.hare
. Default isFALSE
- win.by.elim
TRUE
(default) if the quota is waived when there are no more candidates than vacant seats. Note: there is no lower limit when the quota is waived, so a candidate may be elected on zero votes.- group.nseats
number of seats reserved to members of a group
- group.members
vector of members of the group with reserved seats
- complete.ranking
is
TRUE
by default. This parameter is retained solely for backwards compatibility withvote::stv()
. It has no effect on elections in whichnseats
is explicitly specified in the call tostv()
.- invalid.partial
TRUE
if ballots which do not specify a complete ranking of candidates are informal (aka "invalid") i.e. ignored (with a warning). Default isFALSE
.- verbose
TRUE
for diagnostic output- seed
integer seed for tie-breaking. Warning: if non-
NULL
, the PRNG for R is reseeded prior to every random tie-break among the possibly-elected candidates. We have preserved this functionality in this branch to allow regression against the legacy codebase ofvote::stv()
. Instv()
the default value for seed isNULL
rather than the legacy value of 1234, to mitigate the validity hazard of PRNG reseedings during a stochastic experiment.- quiet
TRUE
to suppress console output- digits
number of significant digits in the output table
- backwards.compatible
TRUE
to regress against vote2_3.2 by disabling $margins, $fuzz, $rankingTable, $safeRank- safety
number of standard deviations on vote-counts, when producing a safeRank by clustering near-ties in a complete ranking
- ...
undocumented intent (preserved from legacy code)
Value
object of class vote.stv
. Note: the winning margins in this object
are valid for the elected candidates and their (total) ranking, but must be
adjusted within tiegroups to be valid for the candidates' (possibly
partial) safeRank.
Details
By default the preferences are not allowed to contain duplicates per ballot.
However, if the argument equal.ranking
is set to TRUE
, ballots 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; …
, or 1; 2; 3; 3; 3; 6; …
, but NOT 1; 1; 2; 3; …
, or NOT 1; 2; 3; 3; 3; 5; 6; …
. If the data contain such invalid
votes, they are automatically corrected and a warning is issued by calling
the correct.ranking
function.
If equal ranking is not allowed (equal.ranking = FALSE
), the argument
invalid.partial
can be used to make ballots containing duplicates or gaps
partially valid. If it is TRUE
, a ballot is considered valid up to a
preference that is in normal case not allowed. For example, ballots 1; 2; 3; 4; 4; 6
or 1; 2; 3; 5; 6; 7
would be both converted into 1; 2; 3; 0; 0; 0
, because the ballots contain valid ranking only up to the third
preference.
By default, ties in the STV algorithm are resolved using the forwards
tie-breaking method, see Newland and Briton (Section 5.2.5). Argument ties
can be set to ”b” in order to use the backwards tie-breaking method, see
O’Neill (2004). In addition, both methods are complemented by the following
“ordered” method: Prior to the STV election candidates are ordered by the
number of first preferences. Equal ranks are resolved by moving to the number
of second preferences, then third and so on. Remaining ties are broken by
random draws. Such complete ordering is used to break any tie that cannot be
resolved by the forwards or backwards method. If there is at least one tie
during the processing, the output contains a row indicating in which count a
tie-break happened (see the ties
element in the Value section for an
explanation of the symbols).
The ordered tiebreaking described above can be analysed from outside of the
stv
function by using the ordered.tiebreak
function for viewing the
a-priori ordering (the highest number is the best and lowest is the worst).
Such ranking is produced by comparing candidates along the columns of the
matrix returned by ordered.preferences
.
Examples
data(food_election)
stv(food_election, safety = 0.0)
#>
#> Results of Single transferable vote
#> ===================================
#> Number of valid votes: 20
#> Number of invalid votes: 0
#> Number of candidates: 5
#> Number of seats: 2
#> Number of unfilled seats: 0
#>
#> Fuzz on safeRank: 0
#> Complete ranking:
#>
#> | | TotalRank|SafeRank | Margin |
#> |:------------|---------:|:--------|:--------:|
#> |Oranges | 2|2 | 1.445111 |
#> |Pears | 5|5 | 0.000000 |
#> |Chocolate | 1|1 | 8.000000 |
#> |Strawberries | 3|3 | 1.777444 |
#> |Sweets | 4|4 | 2.777444 |
#>
#> Vote transfers:
#>
#> | | 1| 2-trans| 2| 3-trans| 3| 4-trans| 4|
#> |:------------|---------:|-------:|-----:|-------:|------:|-------:|-------:|
#> |Oranges | 4.000| 0.000| 4.000| 2| 6.000| 0.000| 6.000|
#> |Pears | 2.000| 0.000| 2.000| -2| | | |
#> |Chocolate | 12.000| -5.332| | | | | |
#> |Strawberries | 1.000| 3.555| 4.555| 0| 4.555| 0.000| 4.555|
#> |Sweets | 1.000| 1.777| 2.777| 0| 2.777| -2.777| |
#> |Tie-breaks | | | | | | | |
#> |Elected | Chocolate| | | | | | Oranges|
#> |Eliminated | | | Pears| | Sweets| | |
#>
#> Elected: Chocolate, Oranges
#>
stv(food_election, nseats = 2)
#>
#> Results of Single transferable vote
#> ===================================
#> Number of valid votes: 20
#> Number of invalid votes: 0
#> Number of candidates: 5
#> Number of seats: 2
#> Number of unfilled seats: 0
#>
#> Fuzz on safeRank: 4.472136
#> Complete ranking:
#>
#> | | TotalRank|SafeRank | Margin |
#> |:------------|---------:|:--------|:--------:|
#> |Oranges | 2|2 | 1.445111 |
#> |Pears | 5|2 | 0.000000 |
#> |Chocolate | 1|1 | 8.000000 |
#> |Strawberries | 3|2 | 1.777444 |
#> |Sweets | 4|2 | 2.777444 |
#>
#> Vote transfers:
#>
#> | | 1| 2-trans| 2| 3-trans| 3| 4-trans| 4|
#> |:------------|---------:|-------:|-----:|-------:|------:|-------:|-------:|
#> |Oranges | 4.000| 0.000| 4.000| 2| 6.000| 0.000| 6.000|
#> |Pears | 2.000| 0.000| 2.000| -2| | | |
#> |Chocolate | 12.000| -5.332| | | | | |
#> |Strawberries | 1.000| 3.555| 4.555| 0| 4.555| 0.000| 4.555|
#> |Sweets | 1.000| 1.777| 2.777| 0| 2.777| -2.777| |
#> |Tie-breaks | | | | | | | |
#> |Elected | Chocolate| | | | | | Oranges|
#> |Eliminated | | | Pears| | Sweets| | |
#>
#> Elected: Chocolate, Oranges
#>