This package provides a set of functions to create optimal line-ups for use in fantasy sports leagues. The purpose of this narrative is to show how to use the FantasySportsDS package. First, load the packages.

library(devtools)
library(stringdist)
library(ICSNP)
install_github('isaacfab/FantasySportsDS')
library(FantasySportsDS)

For starters, you will need to read in the data from your league, Draft Kings - NFL is used as the first application. For now the package is limited to functions for the Draft Kings - NFL and the 2016 season. A '.csv' file is provided by the Draft Kings site when you build a line up. We want to create a descriptive name for each player in order to join each row with other information later. Here we also create a variable (binary only 1 or 0) that if set to 1 requires that player to be in a given lineup.

data(DKSalariesExample)

DKSalariesExample$DescriptiveName<-paste(DKSalariesExample$Name,DKSalariesExample$teamAbbrev,DKSalariesExample$Position,sep=" ")

DKSalariesExample$Require<-0

print(head(DKSalariesExample))

Several things should be observed from the raw data. First, each player has a 'salary' and a line up must be selected such that the total salary does not exceed a given cap (default is 50,000). In addition, a column has the average number of points for a given player. This number is the mean for this season. Draft Kings will include players in the line up selection that are either injured or suspended. You, obviously, want to avoid selecting these players. On the actual website their names have a flag next to them but for analysis or automation we have to remove them ourselves. The first function the FantasySportsDS package provides is an automated method for retrieving current injuries or suspensions (from Yahoo). The first function returns players that are currently ineligible to play. Keep in mind that these functions scrape current data!

data.inel<-FantasySportsDS::injury()

print(data.inel[1:3,])

We want to join the injury information to the draft kings DKSalariesExample.

DKSalariesExample$injury<-"None"
DKSalariesExample$gdc<-"None"
for(i in 1:length(DKSalariesExample[,1])){
    j<-stringdist::amatch(DKSalariesExample$DescriptiveName[i],data.inel$DescriptiveName,maxDist=5)
    if(!is.na(j)){
      DKSalariesExample$injury[i]<-data.inel[["Injury"]][j]
    }
}

print(DKSalariesExample[1:5,])

Now you have to make some decisions on what players you want to exclude. Obviously, you want to rule out anyone who is 'Out' but there is also a category of 'Questionable.' This category often includes high profile players that may need a case-by-case decision. For this example, we will only keep players that are either not injured or are probable. You can subset however you like.

DKSalariesExample<-DKSalariesExample[DKSalariesExample$gdc=="None"|DKSalariesExample$gdc=="P",]
table(DKSalariesExample$injury)

Now that you have removed any players that will likely not be on the field, it is time to start thinking about how to forecast player performance. The following function scrapes fantasy point predictions from 8 fantasy football websites and gives two types of averages. The only arguments that this function accepts is an integer value for the week of the season and the year. Like the injuries, this function returns current values.

forecast<-FantasySportsDS::CombinedForecasts(1,2015)

print(forecast[1:3,])

Need to combine these forecasts with the data.

n<-colnames(forecast)
n<-n[2:length(n)]
for(i in 1:length(n)){
  DKSalariesExample[[n[i]]]<-0
}

#combine the forecasts and the Draft Kings file
for(i in 1:length(DKSalariesExample[,1])){
  j<-stringdist::amatch(DKSalariesExample$DescriptiveName[i],forecast$DescriptiveName,maxDist=5)
  if(!is.na(j)){
    for(k in 1:length(n)){
      DKSalariesExample[[n[k]]][i]<-forecast[[k+1]][j]
    }
  }
}

The quality of the lineup that is played is dependent on how good the forecasts are. There is room here for you to complete your own forecasts from any number of sources such as regression, machine learning, other expert predictions, ownership rates and so on. However, even if you have perfect forecasts you would still have the problem of knowing which combination of players results in the greatest amount of fantasy points (the possible combinations of teams is enormous).

The following function preforms a linear program and returns the optimal lineup from a given set of forecasts. In other words if your forecast are perfect this function will give you the team with the highest score. There are three functional arguments; our data, the forecast column name and the salary cap (defaults to 50,000). Here are three optimal lineups using different sources of forecasting and constraints.

#Optimal Lineup with Average Points Per Game forecast
opt<-FantasySportsDS::DKoptLineUpNFL(DKSalariesExample,"AvgPointsPerGame")
print(opt[,1:4])

#Optimal Lineup with FFToday forecast and require that Russell Wilson is in the lineup
DKSalariesExample$Require[DKSalariesExample$DescriptiveName=="Russell Wilson Sea QB"]<-1
fft_opt<-FantasySportsDS::DKoptLineUpNFL(DKSalariesExample,"FFToday_f")
print(fft_opt[,1:4])

#Optimal Lineup with Average forecast but lower salary cap
avg_opt<-FantasySportsDS::DKoptLineUpNFL(DKSalariesExample,"Average_Robust",45000)
print(avg_opt[,1:4])


isaacfab/FantasySportsDS documentation built on May 28, 2019, 9:56 p.m.