elo
PackageThe elo
package includes functions to address all kinds of Elo calculations.
library(elo)
Most functions begin with the prefix “elo.”, for easy autocompletion.
Vectors or scalars of Elo scores are denoted elo.A
or elo.B
.
Vectors or scalars of wins by team A are denoted by wins.A
.
Vectors or scalars of win probabilities are denoted by p.A
.
Vectors of team names are denoted team.A
or team.B
.
To calculate the probability team.A beats team.B, use elo.prob()
:
elo.A <- c(1500, 1500)
elo.B <- c(1500, 1600)
elo.prob(elo.A, elo.B)
## [1] 0.500000 0.359935
To calculate the score update after the two teams play, use elo.update()
:
wins.A <- c(1, 0)
elo.update(elo.A, elo.B, wins.A, k = 20)
## [1] 10.0000 -7.1987
To calculate the new Elo scores after the update, use elo.calc()
:
elo.calc(elo.A, elo.B, wins.A, k = 20)
## elo.A elo.B
## 1 1510.000 1490.000
## 2 1492.801 1607.199
elo.run
functionTo calculate a series of Elo updates, use elo.run()
. This function has a formula =
and data =
interface. We first load the dataset tournament
.
data(tournament)
str(tournament)
## 'data.frame': 56 obs. of 4 variables:
## $ team.Home : Factor w/ 8 levels "Athletic Armadillos",..: 2 3 4 5 6 7 8 1 3 4 ...
## $ team.Visitor : Factor w/ 8 levels "Athletic Armadillos",..: 1 1 1 1 1 1 1 2 2 2 ...
## $ points.Home : int 8 7 10 9 8 6 7 12 9 11 ...
## $ points.Visitor: num 12 6 13 8 9 8 6 4 2 12 ...
formula =
should be in the format of wins.A ~ team.A + team.B
. The score()
function will help to calculate winners on the fly (1 = win, 0.5 = tie, 0 = loss).
tournament$wins.A <- tournament$points.Home > tournament$points.Visitor
elo.run(wins.A ~ team.Home + team.Visitor, data = tournament, k = 20)
##
## An object of class 'elo.run', containing information on 8 teams and 56 matches.
elo.run(score(points.Home, points.Visitor) ~ team.Home + team.Visitor, data = tournament, k = 20)
##
## An object of class 'elo.run', containing information on 8 teams and 56 matches.
For more complicated Elo updates, you can include the special function k()
in the formula =
argument. Here we’re taking the log of the win margin as part of our update.
elo.run(score(points.Home, points.Visitor) ~ team.Home + team.Visitor +
k(20*log(abs(points.Home - points.Visitor) + 1)), data = tournament)
##
## An object of class 'elo.run', containing information on 8 teams and 56 matches.
It’s also possible to adjust one team’s Elo for a variety of factors (e.g., home-field advantage). The adjust()
special function will take as its second argument a vector or a constant.
elo.run(score(points.Home, points.Visitor) ~ adjust(team.Home, 10) + team.Visitor,
data = tournament, k = 20)
##
## An object of class 'elo.run', containing information on 8 teams and 56 matches.
elo.run()
also recognizes if one of the columns is numeric, and interprets that as a fixed-Elo opponent.
tournament$elo.Visitor <- 1500
elo.run(score(points.Home, points.Visitor) ~ team.Home + elo.Visitor,
data = tournament, k = 20)
##
## An object of class 'elo.run', containing information on 8 teams and 56 matches.
There are several helper functions that are useful to use when interacting with objects of class "elo.run"
.
as.matrix.elo.run()
creates a matrix of running Elos.
e <- elo.run(score(points.Home, points.Visitor) ~ team.Home + team.Visitor,
data = tournament, k = 20)
head(as.matrix(e))
## Athletic Armadillos Blundering Baboons Cunning Cats Defense-less Dogs
## [1,] 1500.000 1500 1500.000 1500.000
## [2,] 1510.000 1490 1500.000 1500.000
## [3,] 1499.712 1490 1510.288 1500.000
## [4,] 1509.721 1490 1510.288 1489.992
## [5,] 1499.441 1490 1510.288 1489.992
## [6,] 1509.457 1490 1510.288 1489.992
## Elegant Emus Fabulous Frogs Gallivanting Gorillas Helpless Hyenas
## [1,] 1500.00 1500.000 1500 1500
## [2,] 1500.00 1500.000 1500 1500
## [3,] 1500.00 1500.000 1500 1500
## [4,] 1500.00 1500.000 1500 1500
## [5,] 1510.28 1500.000 1500 1500
## [6,] 1510.28 1489.984 1500 1500
as.data.frame.elo.run()
gives the long version (perfect, for, e.g., ggplot2
).
str(as.data.frame(e))
## 'data.frame': 120 obs. of 3 variables:
## $ game: num 0 0 0 0 0 0 0 0 1 1 ...
## $ team: Factor w/ 8 levels "Athletic Armadillos",..: 1 2 3 4 5 6 7 8 2 1 ...
## $ elo : num 1500 1500 1500 1500 1500 1500 1500 1500 1490 1510 ...
Finally, last()
will extract the final Elos per team.
last(e)
## Athletic Armadillos Blundering Baboons Cunning Cats
## 1573.246 1418.969 1554.024
## Defense-less Dogs Elegant Emus Fabulous Frogs
## 1452.811 1508.891 1535.245
## Gallivanting Gorillas Helpless Hyenas
## 1483.299 1473.516