Compute a (usually logistic) regression model for a series of matches.

elo.glm(
  formula,
  data,
  family = "binomial",
  weights,
  na.action,
  subset,
  ...,
  running = FALSE,
  skip = 0
)

Arguments

formula

A formula. See the help page for formulas for details.

data

A data.frame in which to look for objects in formula.

family, weights, ...

Arguments passed to glm.

na.action

A function which indicates what should happen when the data contain NAs.

subset

An optional vector specifying a subset of observations.

running

Logical, denoting whether to calculate "running" projected probabilities. If true, a model is fit for group 1 on its own to predict group 2, then groups 1 and 2 to predict 3, then groups 1 through 3 to predict 4, etc. Groups are determined in formula. Omitting a group term re-runs a glm model to predict each observation (a potentially time-consuming operation!)

skip

Integer, denoting how many groups to skip before fitting the running models. This is helpful if groups are small, where glm would have trouble converging for the first few groups. The predicted values are then set to 0.5 for the skipped groups.

Value

An object of class c("elo.glm", "glm"). If running==TRUE, the class "elo.glm.running" is prepended.

Details

The formula syntax is the same as other elo functions. A data.frame of indicator variables is built, where an entry is 1 if a team is home, 0 if a team didn't play, and -1 if a team is a visitor. Anything passed to adjust() in formula is also put in the data.frame. A glm model is then run to predict wins or margin of victory.

With this setup, the intercept represents the home-field advantage. Neutral fields can be indicated using the neutral() function, which sets the intercept to 0.

Note that any weights specified in players() will be ignored.

This is essentially the Bradley-Terry model.

References

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

See also

Examples

data(tournament)
elo.glm(score(points.Home, points.Visitor) ~ team.Home + team.Visitor, data = tournament,
  subset = points.Home != points.Visitor)
#> 
#> Call:  stats::glm(formula = wins.A ~ . - 1, family = family, data = dat.qr, 
#>     weights = wts, subset = NULL, na.action = stats::na.pass)
#> 
#> Coefficients:
#>              home.field    `Athletic Armadillos`     `Blundering Baboons`  
#>                  1.0307                   1.4289                  -0.9637  
#>          `Cunning Cats`      `Defense-less Dogs`           `Elegant Emus`  
#>                  0.5377                  -1.7413                   0.3931  
#>        `Fabulous Frogs`  `Gallivanting Gorillas`  
#>                  0.8489                   0.3994  
#> 
#> Degrees of Freedom: 51 Total (i.e. Null);  43 Residual
#> Null Deviance:	    70.7 
#> Residual Deviance: 48.04 	AIC: 64.04
elo.glm(mov(points.Home, points.Visitor) ~ team.Home + team.Visitor, data = tournament,
  family = "gaussian")
#> 
#> Call:  stats::glm(formula = wins.A ~ . - 1, family = family, data = dat.qr, 
#>     weights = wts, subset = NULL, na.action = stats::na.pass)
#> 
#> Coefficients:
#>              home.field    `Athletic Armadillos`     `Blundering Baboons`  
#>                  2.6964                   3.1250                  -2.4375  
#>          `Cunning Cats`      `Defense-less Dogs`           `Elegant Emus`  
#>                  0.3125                  -3.5000                  -0.9375  
#>        `Fabulous Frogs`  `Gallivanting Gorillas`  
#>                  0.6875                   0.2500  
#> 
#> Degrees of Freedom: 56 Total (i.e. Null);  48 Residual
#> Null Deviance:	    2161 
#> Residual Deviance: 1295 	AIC: 352.8