% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/rank_candidates.R
\name{rank_candidates}
\alias{rank_candidates}
\title{Rank candidates based on voter preferences}
\usage{
rank_candidates(
  voters,
  candidates,
  weights = NULL,
  committee_size = NULL,
  method = "av",
  borda_score = TRUE,
  shuffle_candidates = TRUE,
  check = FALSE
)
}
\arguments{
\item{voters}{(\code{list()}) \cr
A list of subsets (\code{character} vectors), where each subset contains the
candidates approved or selected by a voter.}

\item{candidates}{(\code{character()}) \cr
A vector of all candidates to be ranked.}

\item{weights}{(\code{numeric()|NULL}) \cr
A numeric vector of non-negative weights representing each voter's influence.
Larger weight, higher influence.
Must have the same length as \code{voters}.
If \code{NULL} (default), all voters are assigned equal weights of 1, representing
equal influence.}

\item{committee_size}{(\code{integer(1)|NULL})\cr
Number of top-ranked candidates to return.
Default (\code{NULL}) returns all candidates.}

\item{method}{(\code{character(1)}) \cr
The ranking voting method to use. Must be one of: \code{"av"}, \code{"sav"}, \code{"seq_pav"},
\code{"seq_phragmen"}. See Details.}

\item{borda_score}{(\code{logical(1)}) \cr
Whether to include a \code{borda_score} column in the output, which provides a
normalized score based on the candidate's rank.
If \code{TRUE} (default), the \code{borda_score} is calculated as \eqn{(p - i) / (p - 1)},
where \eqn{p} is the total number of candidates and \eqn{i} is the candidate's rank.}

\item{shuffle_candidates}{(\code{logical(1)}) \cr
Whether to randomly shuffle candidates before ranking.
This provides random tie-breaking and avoids deterministic bias when scores
are equal. Default is \code{TRUE}.}

\item{check}{(\code{logical(1)}) \cr
Whether to run additional voter-integrity checks. When \code{TRUE}, each voter
must approve at least one candidate, approvals must be unique per voter, and
all approved candidates must appear in \code{candidates}. Use \code{FALSE} to skip
these checks when inputs are known to be valid.}
}
\value{
A \code{data.frame} with columns:
\itemize{
\item \code{"candidate"}: Candidate names.
\item \code{"score"}: Scores assigned to each candidate based on the selected method
(if applicable).
\item \code{"norm_score"}: Normalized scores (if applicable), scaled to the range
\eqn{[0,1]}, which can be loosely interpreted as \strong{selection probabilities}
(see Meinshausen et al. (2010) for an example in Machine Learning research
where the goal is to perform stable feature selection).
\item \code{"borda_score"}: Borda scores for method-agnostic comparison, ranging in
\eqn{[0,1]}, where the top candidate receives a score of 1 and the lowest-ranked
candidate receives a score of 0.
}

Candidates are ordered by decreasing \code{"score"}, or by \code{"borda_score"} if the
method returns only rankings.
}
\description{
Calculates a ranking of candidates based on voters' preferences.
Approval-Based Committe (ABC) rules are based on Lackner et al. (2023).
For an example use in Machine Learning for ensemble feature selection,
see Zobolas et al. (2026).
}
\details{
We implement several consensus-based ranking methods, where voters express
preferences for candidates.
The framework has three components:
\itemize{
\item \strong{Voters}: A list where each element is the set of approved candidates for
a single voter.
\item \strong{Candidates}: A character vector of all possible candidates. This vector
can be shuffled to randomize tie-breaking across methods.
\item \strong{Weights}: A numeric vector giving each voter’s influence. Equal weights
mean equal influence; differing weights reflect varying importance.
}

This function is a thin wrapper that dispatches to method-specific implementations.
Supported methods include:
\enumerate{
\item Approval Voting (\code{method = "av"}), calls \code{\link[=av]{av()}}
\item Satisfaction Approval Voting (\code{method = "sav"}), calls \code{\link[=sav]{sav()}}
\item Sequential Proportional Approval Voting (\code{method = "seq_pav"}), calls \code{\link[=seq_pav]{seq_pav()}}
\item Sequential Phragmen’s Rule (\code{method = "seq_phragmen"}), calls \code{\link[=seq_phragmen]{seq_phragmen()}}
}

All methods support voter weights.

For method-agnostic comparisons, we compute \strong{borda scores}, which map each
candidate’s rank to a normalized scale across methods that may otherwise
return different score scales or only ordinal rankings.

For sequential methods such as \code{"seq_pav"} and \code{"seq_phragmen"}, the
\code{committee_size} parameter can speed up computation by selecting only the top
\eqn{N} candidates instead of producing a full ranking. For non-sequential methods
(e.g., \code{"sav"} or \code{"av"}), it simply truncates the final ranking to the top
\eqn{N} candidates.
}
\examples{
# 5 candidates
candidates = paste0("V", seq_len(5))

# 4 voters
voters = list(
  c("V3", "V1", "V4"),
  c("V3", "V1"),
  c("V3", "V2"),
  c("V2", "V4")
)

# voter weights
weights = c(1.1, 2.5, 0.8, 0.9)

# Approval voting (all voters equal)
rank_candidates(voters, candidates)

# Approval voting (voters unequal)
rank_candidates(voters, candidates, weights)

# Satisfaction Approval voting (voters unequal, no borda score)
rank_candidates(voters, candidates, weights, method = "sav", borda_score = FALSE)

# Sequential Proportional Approval voting (voters equal, no borda score)
rank_candidates(voters, candidates, method = "seq_pav", borda_score = FALSE)

# Sequential Phragmen's Rule (voters equal)
rank_candidates(voters, candidates, method = "seq_phragmen", borda_score = FALSE)

}
\references{
Lackner M, Skowron P (2023). \emph{Multi-Winner Voting with Approval Preferences}.
Springer Nature, 121 p. \doi{10.1007/978-3-031-09016-5}.

Zobolas J, George A, Lopez A, Fischer S, Becker M, Aittokallio T (2026).
"Prognostic biomarker discovery in pancreatic cancer through hybrid ensemble
feature selection and multi-omics data." \emph{BioData Mining}. \doi{10.1186/s13040-026-00546-0}.

Meinshausen N, Buhlmann P (2010). "Stability Selection." \emph{Journal of the Royal
Statistical Society Series B: Statistical Methodology}, 72(4), 417-473.
\doi{10.1111/J.1467-9868.2010.00740.X}.
}
