Created
August 20, 2024 14:08
-
-
Save JoGall/0d257e1f49c2ecf8ff6170b96b3f2506 to your computer and use it in GitHub Desktop.
Expected Points (xPts) for FantasyPL draft head-to-head league
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Calculate expected points for a FantasyPL draft, head-to-head league. | |
# | |
# Calculate expected points (xPts) and expected rank (xRank) for each | |
# team in a head-to-head draft league as the average points (i.e. 0, 1, 3) | |
# expected against all teams in that league each gameweek, not just the actual | |
# opponent. | |
# | |
# @param leagueid: integer | |
library(dplyr) | |
library(data.table) | |
library(jsonlite) | |
library(glue) | |
xpts_draft_h2h <- function(leagueid) { | |
fpl_json <- fromJSON(glue::glue("https://draft.premierleague.com/api/league/{leagueid}/details")) | |
# get fixtures | |
fixtures_df <- fpl_json$matches | |
# get manager lookup | |
manager_df <- fpl_json$league_entries %>% | |
select(id, name = entry_name) | |
# get true head to head table | |
table_df <- fpl_json$standings %>% | |
select(id=league_entry, pts=points_for, h2h_pts=total, rank=rank) | |
# keep completed games only | |
fixtures_df <- fixtures_df[fixtures_df$finished == 1,] | |
scores_df <- rbind( | |
fixtures_df %>% select(event, id = league_entry_1, pts = league_entry_1_points), | |
fixtures_df %>% select(event, id = league_entry_2, pts = league_entry_2_points) | |
) | |
xpts_rounds <- lapply(unique(scores_df$event), function(i) { | |
ss <- scores_df[scores_df$event == i,] | |
lapply(unique(ss$id), function(j) { | |
score <- ss[ss$id == j,]$pts | |
opp_scores <- ss[ss$id != j,]$pts | |
h2h_xpts <- (sum(as.numeric(score > opp_scores) * 3) + sum(as.numeric(score == opp_scores) * 1)) / length(opp_scores) | |
data.frame(id = j, gw = i, pts = score, h2h_xpts) | |
}) %>% | |
plyr::rbind.fill() | |
}) %>% | |
plyr::rbind.fill() | |
# table by expected points | |
xpts_table <- xpts_rounds %>% | |
group_by(id) %>% | |
summarise( | |
score = sum(pts), | |
h2h_xpts = sum(h2h_xpts)) %>% | |
ungroup() %>% | |
arrange(-h2h_xpts) | |
output_df <- left_join( | |
table_df, | |
xpts_table, | |
on='id') %>% | |
left_join(manager_df, on = 'id') %>% | |
mutate(xrank = data.table::frank(., -h2h_xpts, score, -h2h_pts, ties.method='min')) %>% | |
arrange(xrank, name) %>% | |
select(rank, team=name, score, pts=h2h_pts, xPts=h2h_xpts, xRank=xrank) | |
return(output_df) | |
} | |
# # example usage | |
# xpts_draft_h2h(81315) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment