Get FPL Review data.

fpl_review <- read.csv("fplreview_1691019313.csv")

Load packages.

library(tidyverse)
library(lpSolve)

Team formation

Num_G = 2
Num_D = 5
Num_M = 5
Num_F = 3

Squad value

team_value = 100

Create vectors for each position.

fpl_review$Goalkeeper = ifelse(fpl_review$Pos == "G", 1, 0)
fpl_review$Defender = ifelse(fpl_review$Pos == "D", 1, 0)
fpl_review$Midfielder = ifelse(fpl_review$Pos == "M", 1, 0)
fpl_review$Forward = ifelse(fpl_review$Pos == "F", 1, 0)

Create team constraints.

team_constraint = unlist(lapply(unique(fpl_review$Team), function(x, fpl_review){
ifelse(fpl_review$Team == x, 1, 0)
}, fpl_review = fpl_review))

Objective function

objective.fn = 
fpl_review$X1_Pts +
fpl_review$X2_Pts +
fpl_review$X3_Pts +
fpl_review$X4_Pts +
fpl_review$X5_Pts 

Constraints matrix

const.mat = matrix(c(fpl_review$Goalkeeper, fpl_review$Defender, fpl_review$Midfielder, fpl_review$Forward,
fpl_review$BV, team_constraint),
nrow=(5 + length(unique(fpl_review$Team))),
byrow=TRUE)

Constraint directions

const.dir <- c("=", "=", "=", "=", "<=", rep("<=", 20))

Right hand side of equation

const.rhs = c(Num_G, Num_D, Num_M, Num_F, team_value, rep(3, 20))

Solve the linear equation.

mod = lp(direction = "max", objective.fn, const.mat, const.dir, const.rhs, all.bin=TRUE, all.int=TRUE)

Dream Squad for Five Games

dream_squad <- fpl_review[which(mod$solution==1),]
dream_squad %>% 
  arrange(desc(Goalkeeper), desc(Defender), desc(Midfielder), desc(Forward)) %>%
  summarise(Name, Team, Pos, BV, X1_Pts, X2_Pts, X3_Pts, X4_Pts, X5_Pts)
          Name        Team Pos  BV X1_Pts X2_Pts X3_Pts X4_Pts X5_Pts
1   Ederson M.    Man City   G 5.5   4.21   3.85   4.34   4.13   3.74
2        Onana     Man Utd   G 5.0   4.15   3.37   4.10   3.14   3.60
3      Gabriel     Arsenal   D 5.0   4.23   3.33   3.67   2.78   3.34
4    Estupiñan    Brighton   D 5.0   4.80   3.53   3.56   2.85   2.04
5     Chilwell     Chelsea   D 5.5   3.21   3.54   5.18   4.46   3.65
6        James     Chelsea   D 5.5   3.09   3.38   4.95   4.32   3.50
7        Rúben    Man City   D 5.5   3.96   3.42   4.04   3.89   3.21
8     Ødegaard     Arsenal   M 8.5   5.76   4.80   5.78   4.41   4.57
9         Saka     Arsenal   M 8.5   6.93   5.70   6.95   5.25   5.38
10      Mbeumo   Brentford   M 6.5   4.67   4.92   5.41   5.58   3.53
11 B.Fernandes     Man Utd   M 8.5   5.99   4.42   6.24   3.94   5.36
12    Rashford     Man Utd   M 9.0   6.11   4.53   6.28   3.93   5.30
13     Watkins Aston Villa   F 8.0   3.93   5.30   4.56   3.60   5.20
14      Nkunku     Chelsea   F 7.5   3.93   4.09   5.09   4.69   4.04
15   J.Alvarez    Man City   F 6.5   3.54   3.50   3.78   4.27   3.39
Comment: Looks good, but do I really need two high scoring goalkeepers when I could put the money to better use elsewhere?

Week 1 starting eleven from squad

week_1 <- dream_squad %>% top_n(11, X1_Pts) %>%
  arrange(-X1_Pts) %>%
  summarise(Name, Team, Pos, X1_Pts)
week_1
          Name        Team Pos X1_Pts
1         Saka     Arsenal   M   6.93
2     Rashford     Man Utd   M   6.11
3  B.Fernandes     Man Utd   M   5.99
4     Ødegaard     Arsenal   M   5.76
5    Estupiñan    Brighton   D   4.80
6       Mbeumo   Brentford   M   4.67
7      Gabriel     Arsenal   D   4.23
8   Ederson M.    Man City   G   4.21
9        Onana     Man Utd   G   4.15
10       Rúben    Man City   D   3.96
11     Watkins Aston Villa   F   3.93
12      Nkunku     Chelsea   F   3.93
Comment: Oh dear! Two goalkeepers.

Best squad for today regardless of five-week plan

objective.fn = fpl_review$X1_Pts

mod2 = lp(direction = "max", objective.fn, const.mat, const.dir, const.rhs, all.bin=TRUE, all.int=TRUE)

dream_squad_for_today <- fpl_review[which(mod2$solution==1),]
dream_squad_for_today %>% 
  arrange(desc(X1_Pts)) %>%
  summarise(Name, Team, Pos, BV, X1_Pts)
          Name           Team Pos  BV X1_Pts
1         Saka        Arsenal   M 8.5   6.93
2     Rashford        Man Utd   M 9.0   6.11
3  B.Fernandes        Man Utd   M 8.5   5.99
4     Ødegaard        Arsenal   M 8.5   5.76
5          Eze Crystal Palace   M 6.5   4.90
6     Trippier      Newcastle   D 6.5   4.88
7    Estupiñan       Brighton   D 5.0   4.80
8         Dunk       Brighton   D 5.0   4.45
9         Shaw        Man Utd   D 5.5   4.44
10     Gabriel        Arsenal   D 5.0   4.23
11     Solanke    Bournemouth   F 6.5   4.22
12  Ederson M.       Man City   G 5.5   4.21
13        Isak      Newcastle   F 7.5   4.15
14      Steele       Brighton   G 4.5   4.00
15      Nkunku        Chelsea   F 7.5   3.93
Comment: The weakness of the above models is that they don’t automatically double the points of the player with the most predicted points (the captain’s). If Haaland were chosen as a shoo-in captain, what would be the best 14-man squad to support him for the next five weeks?

Best fourteen-man squad over five weeks with Haaland chosen automatically

Num_G = 2
Num_D = 5
Num_M = 5
Num_F = 2

team_value = 86

const.rhs = c(Num_G, Num_D, Num_M, Num_F, team_value, rep(3, 20))

objective.fn = 
fpl_review$X1_Pts +
fpl_review$X2_Pts +
fpl_review$X3_Pts +
fpl_review$X4_Pts +
fpl_review$X5_Pts 

mod3 = lp(direction = "max", objective.fn, const.mat, const.dir, const.rhs, all.bin=TRUE, all.int=TRUE)

dream_squad_with_Haaland <- fpl_review[which(mod3$solution==1),]
dream_squad_with_Haaland %>% 
  arrange(desc(Goalkeeper), desc(Defender), desc(Midfielder), desc(Forward)) %>%
  summarise(Name, Team, Pos, BV, X1_Pts, X2_Pts, X3_Pts, X4_Pts, X5_Pts)
           Name          Team Pos  BV X1_Pts X2_Pts X3_Pts X4_Pts X5_Pts
1  Arrizabalaga       Chelsea   G 5.0   3.50   3.67   4.53   4.14   3.84
2    Ederson M.      Man City   G 5.5   4.21   3.85   4.34   4.13   3.74
3       Gabriel       Arsenal   D 5.0   4.23   3.33   3.67   2.78   3.34
4      Chilwell       Chelsea   D 5.5   3.21   3.54   5.18   4.46   3.65
5         James       Chelsea   D 5.5   3.09   3.38   4.95   4.32   3.50
6         Rúben      Man City   D 5.5   3.96   3.42   4.04   3.89   3.21
7        Romero         Spurs   D 4.5   2.80   2.44   3.03   2.98   3.88
8          Saka       Arsenal   M 8.5   6.93   5.70   6.95   5.25   5.38
9        Mbeumo     Brentford   M 6.5   4.67   4.92   5.41   5.58   3.53
10      Andreas        Fulham   M 5.5   3.97   4.26   3.06   2.73   4.94
11  B.Fernandes       Man Utd   M 8.5   5.99   4.42   6.24   3.94   5.36
12  Gibbs-White Nott'm Forest   M 6.0   3.36   5.17   3.21   3.25   4.59
13      Watkins   Aston Villa   F 8.0   3.93   5.30   4.56   3.60   5.20
14    J.Alvarez      Man City   F 6.5   3.54   3.50   3.78   4.27   3.39
Comment: Looks promising, but Romero rather than Mings or Botman? This model needs manual intervention.
Footnote: And there are four City players.
Thanks for reading!