computeELORanking <- function(games, k = 30, initialValue = 1500) { ranking <- data.frame(Date=as.Date(character()), Team=character(), Points=numeric()) elos <- numeric() # current elo values names(elos) <- character() # named vector ("dictionary") games <- na.omit(games) games <- games[order(games$Date),] for (i in 1:nrow(games)) # loop over all rows (games) { homeTeam <- games$HomeTeam[i] awayTeam <- games$AwayTeam[i] # set initial ELO value if necessary if (!(homeTeam %in% names(elos))) { elos[homeTeam]=initialValue } if (!(awayTeam %in% names(elos))) { elos[awayTeam]=initialValue } # compute elo rating as described on https://en.wikipedia.org/wiki/Elo_rating_system gd <- games$FTHG[i] - games$FTAG[i] W_home <- 0.5 if (gd > 0) { W_home <- 1 } else if (gd < 0) { W_home <- 0 } We_home <- 1/(1+10^((elos[awayTeam]-elos[homeTeam])/400)) # expected result P <- k*(W_home-We_home) # change elos[homeTeam] <- elos[homeTeam] + P elos[awayTeam] <- elos[awayTeam] - P ranking <- tibble::add_row(ranking, Date = games$Date[i], Team = homeTeam, Points = elos[homeTeam]) ranking <- tibble::add_row(ranking, Date = games$Date[i], Team = awayTeam, Points = elos[awayTeam]) } return(list(ranking, elos)) }