knitr::opts_chunk$set(
  collapse = FALSE,
  comment = "#>"
)

Setup

Library the package and a solver (glpk)

library(dfsOptimizer)

Building Optimizer and getting lineups

Example of instantiating an Optimizer object, adding players from an internal dataset (nhl_players), generating 5 lineups.

# Instantiate
mod <- create_optimizer(site = 'DRAFTKINGS', sport = 'HOCKEY', contest_type = 'CLASSIC')
# Add players
mod <- add_players_from_df(mod, nhl_players)
# Generate lineups
lineups <- build_lineups(mod, num_lineups = 5, verbose = FALSE)

View the lineups

You can view the lineups simply by calling the object saved by build_lineups.

lineups

You can access the individual lineups with standard '[' indexing

lineups[1]
lineups[[2]]

Finally, you may to extract the lineups to a list, To do so, you can simply run as.list(lineups)

# Here we're getting the total fpts from every lineup using sapply
colSums(sapply(as.list(lineups), '[[', 'fpts'))

Lineup Summary

Lineup summary provides information about how often individual players were selected for lineups (count and percentage), which teams were selected most often, and a measure of lineup variance (higher Jaccard Distance means more variance across lineups)

# Summary stats
summary(lineups)

Export the lineups

The format of the file output by export_lineups is determined by the Site, Sport, and Contest Type.

export_lineups(lineups, file = 'lineup_export.csv')

Including Previously Generated Lineups

There may be cases where you want to include previously generated lineups. For example, let's say you want certain players' variance to be dependent -- like if a hockey center's projection decreases randomly, his wingers' projections should decrease a similar amount. By including previously generated lineups, you can alter the projections before each iteration of the model, but still be sure you're not generating the same lineup twice.

# Make an empty object called Lineups
lineups <- list()

# Pull the initial player data, to build off of
player_data <- get_player_data(mod)

# Iterate for as many lineups as you'd like, let's say 20
for (nl in 1:20) {
  # Apply your formula for dependent-randomness
  # Get a single percentage adjustment (say, 10%)
  random_adjustment <- runif(1, -.1, .1)

  # We'll apply it to COL Cs and Ws from our nhl_players set, as an illustration
  # Note the data.table notation here -- we're saying for ALL Cs and Ws on Colorado,
  # Let's apply the _same_ random adjustment.  You could easily loop this across teams,
  # and lines if you had line-information
  player_data[team == 'COL' && position %in% c('C','W'), 
              fpts := fpts * (1 + random_adjustment)]

  # Now add that updated data back into the optimizer
  mod <- add_players_from_df(mod, player_data)

  # And Build the next lineup.Note the inclusion of the `existing_lineups` parameter
  lineups <- build_lineups(mod, num_lineups = 1, existing_lineups = lineups, verbose = FALSE)
}

Or, as another example, let's say you need 100 lineups - after the first 50, you notice the model is overwhelmingly selecting forwards from two teams, COL and EDM. You want to block those forwards in the next 50 lineups, but allow for any number of D or G from those teams.

# Build 50 lineups
lineups <- build_lineups(mod, num_lineups = 50, verbose = FALSE) 

# Block any COL/EDM forwards
player_data <- get_player_data(mod)
ids_to_block <- player_data[team %in% c('COL','EDM') & position %in% c('C','W'), ]$id
mod <- block_players_by_id(mod, ids_to_block)

# Build 50 more lineups, which do not match any of the previous
lineups_new <- build_lineups(mod, num_lineups = 50, existing_lineups = lineups, verbose = FALSE) 


anthonyshook/dfsOptimizer documentation built on Jan. 4, 2023, 11:36 a.m.