Summary
This text will be hidden
The app below is a knaps
Summary
This text will be hidden
ack optimizer for dfs, which allows the user to pick players to base an optimization of off. The app works how its intended however I wanted to add a feature where AFTER the lineups are generated I want to preform the below function on the generated lineups and render the output in 'For Mass Entry' tab.
library(shiny)
library(lpSolveAPI)
library(tidyr)
library(dplyr)
library(readr)
library(purrr)
library(googlesheets4)
library(gdata)
FDprojection<-read_csv("https://raw.githubusercontent.com/NahomKun/data/master/FDprojection.csv")
FDprojection$Position <- sub("/.*", "", FDprojection$Position)
FDprojection <- mutate(FDprojection,Value= round((Points/Salary)*1000,2))
DKprojection <- read_csv("https://raw.githubusercontent.com/NahomKun/data/master/DKprojection.csv")
DKprojection$Position <- sub("/.*", "", DKprojection$Position)
DKprojection <- mutate(DKprojection,Value= round((Points/Salary)*1000,2))
DK <- read_csv("https://raw.githubusercontent.com/NahomKun/data/master/GameLogs.csv")
find_teams_FD <- function(FDprojection, cap, constraint = c("none", "all_diff", "no_opp"),
league = c("FanDuel", "DraftKings"), setplayers = NULL, removeteams = NULL)
{
colnames(FDprojection) <- c("ID", "Position", "Player", "Salary", "Team","Opp", "Points", "Value")
pg <- ifelse(FDprojection$Position == "PG", 1,0)
sg <- ifelse(FDprojection$Position == "SG", 1,0)
sf <- ifelse(FDprojection$Position == "SF", 1,0)
pf <- ifelse(FDprojection$Position == "PF", 1,0)
c <- ifelse(FDprojection$Position == "C", 1,0)
lpfantasy <- make.lp(0, nrow(FDprojection))
set.objfn(lpfantasy, FDprojection$Points)
set.type(lpfantasy, seq(1, nrow(FDprojection), by=1), type = c("binary"))
if(league == "FanDuel") {
add.constraint(lpfantasy, pg, "=", 2)
add.constraint(lpfantasy, sg, "=", 2)
add.constraint(lpfantasy, sf, "=", 2)
add.constraint(lpfantasy, pf, "=", 2)
add.constraint(lpfantasy, c, "=", 1)
}
if(league == "DraftKings"){
dk_total <- pg + sg + sf + pf + c
add.constraint(lpfantasy, pg, "<=", 3)
add.constraint(lpfantasy, sg, "<=", 3)
add.constraint(lpfantasy, sf, "<=", 3)
add.constraint(lpfantasy, pf, "<=", 3)
add.constraint(lpfantasy, c, "<=", 2)
add.constraint(lpfantasy, dk_total, "=", 8)
}
add.constraint(lpfantasy, FDprojection$Salary, "<=", cap)
lp.control(lpfantasy, sense = 'max')
team_names <- levels(factor(FDprojection$Team))
constraint <- match.arg(constraint)
if(constraint == "no_opp") {
team_names <- levels(factor(FDprojection$Team))
for (i in 1:lenght(team_names)) {
no_two <- ifelse(FDprojection$Team == team_names[i],1,0)
add.constraint(lpfantasy, no_two, "<=",2)
}
for (j in 1:nrow(FDprojection)) {
no_opposing <- ifelse(FDprojection$Opponent == FDprojection$Team[j], 1,0)
no_opposing[j] <- 1
for (k in 1:nrow(FDprojection)) {
out <- rep(0 , nrow(FDprojection))
out[j] <- 1
out[k] <- no_opposing[k]
add.constraint(lpfantasy, out, "<=",1)
}
}
}
if(!is.null(setplayers)){
if(league == "FanDuel") {
if((sum(setplayers$Position == "PG") > 2) || (sum(setplayers$Position == "SG") > 2) || (sum(setplayers$Position == "SF") > 2) ||
(sum(setplayers$Position == "PF") > 2) || (sum(setplayers$Position == "C") > 1))
stop("One of your position has too many players")
}
if(league == "DraftKings"){
if((sum(setplayers$Position == "PG") > 3) || (sum(setplayers$Position == "SG") > 3) || (sum(setplayers$Position == "SF") > 3) ||
(sum(setplayers$Position == "PF") > 3) || (sum(setplayers$Position == "C") > 2))
stop("One of your position has too many players")
}
if(!is.null(removeteams)){
if(nrow(removeteams) != nrow(FDprojection))
stop("Your team restriction do not match the number of players included in the projection set")
for (m in 1:ncol(removeteams)) {
add.constraint(lpfantasy, removeteams[, m], "<=", 8)
}
}
team <- data.frame(matrix(0,1,ncol(FDprojection) + 2))
colnames(team) <- c(colnames(FDprojection), "TeamSalary", "TeamPoints")
solve.lpExtPtr(lpfantasy)
if(solve.lpExtPtr(lpfantasy)!= 0)
stop("Optimization failed at some point")
team_select <- subset(data.frame(FDprojection, get.variables(lpfantasy)), get.variables.lpfantasy. == 1)
team_select$get.variables.lpfantasy. <- NULL
team_select$TeamSalary <- sum(team_select$Salary)
team_select$TeamPoints <- sum(team_select$Points)
team <- rbind(team, team_select)
team <- team[-1,]
rownames(team) <- NULL
team
}
FD_top_teams <- function(FDprojection, num_top, cap, constraint, league, setplayers){
result <- find_teams_FD(FDprojection, cap, constraint = constraint, league = league, setplayers)
restrict <- as.matrix(rep(0,nrow(FDprojection)))
restrict[match(result$ID, FDprojection$ID), 1] <-1
j <- 1
while (j < num_top) {
resultnew <- find_teams_FD(FDprojection, cap, constraint = constraint, league = league, setplayers, removeteams = restrict)
restrict <- cbind(restrict, rep(0, nrow(restrict)))
restrict[match(resultnew$ID, FDprojection$ID), j] <- 1
result <- rbind(result, resultnew)
j <- j + 1
}
TeamNumber <- rep(1:num_top, each = 9)
result <- cbind.data.frame(result, TeamNumber)
result
}
choiceList <- sort(FDprojection$Player)
ui <- fluidPage(
navbarPage(
title = 'DFS Lineups and Projections',
tabPanel('FanDuel Projection',DT::dataTableOutput('FDprojection')),
tabPanel('DraftKings Projection', DT::dataTableOutput('DKprojection')),
tabPanel('FanDuel Lineup Maker', selectizeInput("Player", "Choose Upto 5 Players",
choices=choiceList, multiple = TRUE, options = list(maxItems =5)),
tableOutput("Lineups"),
actionButton("Lineups","Make Lineups")),
tabPanel('DraftKings Single Optimal Lineup',DT::dataTableOutput('DK')),
tabPanel('For Mass Entry',DT::dataTableOutput('Output'))
)
)
server <-function(input, output) {
# display 50 rows initially
output$FDprojection <- DT::renderDataTable(
DT::datatable(FDprojection, options = list(pageLength = 50))
)
# the 2nd element contains menu labels
output$DKprojection <- DT::renderDataTable(
DT::datatable(DKprojection, options = list(pageLength = 50))
)
# you can also use paging = FALSE to disable pagination
Lineups <- eventReactive(input$Lineups,{
FD_top_teams(FDprojection,150, 60000, constraint = "none", league = "FanDuel",
setplayers = subset(FDprojection, Player %in% input$Player))
} )
output$Lineups <- renderTable({
Lineups()
})
# you can also use paging = FALSE to disable pagination
output$DK <- DT::renderDataTable(
DT::datatable(DK, options = list(paging = FALSE))
)
output$Output <- DT::renderDataTable(
DT::datatable(Output, options = list(paging = FALSE))
)
}
shinyApp(ui, server)