Fantasy Football Analysis


Setup

Set Global Options

knitr::opts_chunk$set(
    dpi = 200,
    warning = FALSE,
    message = FALSE
)


Load Relevant Libraries

library(tidyverse)
library(viridis)
library(ggthemes)
library(scales)
library(rmarkdown)


Load Data

FF_Opportunity_2006_2021 <- read_rds('FF_Opportunity_2006_2021.rds')


Data Preview
FF_Opportunity_2006_2021 %>% 
arrange(desc(season)) %>% 
select(
    season,
    posteam,
    week, 
    full_name,
    position,
    total_fantasy_points
) %>% 
head(1000) %>% 
paged_table()


All Columns List

names(FF_Opportunity_2006_2021)
##   [1] "season"                         "posteam"                       
##   [3] "week"                           "game_id"                       
##   [5] "player_id"                      "full_name"                     
##   [7] "position"                       "pass_attempt"                  
##   [9] "rec_attempt"                    "rush_attempt"                  
##  [11] "pass_air_yards"                 "rec_air_yards"                 
##  [13] "pass_completions"               "receptions"                    
##  [15] "pass_completions_exp"           "receptions_exp"                
##  [17] "pass_yards_gained"              "rec_yards_gained"              
##  [19] "rush_yards_gained"              "pass_yards_gained_exp"         
##  [21] "rec_yards_gained_exp"           "rush_yards_gained_exp"         
##  [23] "pass_touchdown"                 "rec_touchdown"                 
##  [25] "rush_touchdown"                 "pass_touchdown_exp"            
##  [27] "rec_touchdown_exp"              "rush_touchdown_exp"            
##  [29] "pass_two_point_conv"            "rec_two_point_conv"            
##  [31] "rush_two_point_conv"            "pass_two_point_conv_exp"       
##  [33] "rec_two_point_conv_exp"         "rush_two_point_conv_exp"       
##  [35] "pass_first_down"                "rec_first_down"                
##  [37] "rush_first_down"                "pass_first_down_exp"           
##  [39] "rec_first_down_exp"             "rush_first_down_exp"           
##  [41] "pass_interception"              "rec_interception"              
##  [43] "pass_interception_exp"          "rec_interception_exp"          
##  [45] "rec_fumble_lost"                "rush_fumble_lost"              
##  [47] "pass_fantasy_points_exp"        "rec_fantasy_points_exp"        
##  [49] "rush_fantasy_points_exp"        "pass_fantasy_points"           
##  [51] "rec_fantasy_points"             "rush_fantasy_points"           
##  [53] "total_yards_gained"             "total_yards_gained_exp"        
##  [55] "total_touchdown"                "total_touchdown_exp"           
##  [57] "total_first_down"               "total_first_down_exp"          
##  [59] "total_fantasy_points"           "total_fantasy_points_exp"      
##  [61] "pass_completions_diff"          "receptions_diff"               
##  [63] "pass_yards_gained_diff"         "rec_yards_gained_diff"         
##  [65] "rush_yards_gained_diff"         "pass_touchdown_diff"           
##  [67] "rec_touchdown_diff"             "rush_touchdown_diff"           
##  [69] "pass_two_point_conv_diff"       "rec_two_point_conv_diff"       
##  [71] "rush_two_point_conv_diff"       "pass_first_down_diff"          
##  [73] "rec_first_down_diff"            "rush_first_down_diff"          
##  [75] "pass_interception_diff"         "rec_interception_diff"         
##  [77] "pass_fantasy_points_diff"       "rec_fantasy_points_diff"       
##  [79] "rush_fantasy_points_diff"       "total_yards_gained_diff"       
##  [81] "total_touchdown_diff"           "total_first_down_diff"         
##  [83] "total_fantasy_points_diff"      "pass_attempt_team"             
##  [85] "rec_attempt_team"               "rush_attempt_team"             
##  [87] "pass_air_yards_team"            "rec_air_yards_team"            
##  [89] "pass_completions_team"          "receptions_team"               
##  [91] "pass_completions_exp_team"      "receptions_exp_team"           
##  [93] "pass_yards_gained_team"         "rec_yards_gained_team"         
##  [95] "rush_yards_gained_team"         "pass_yards_gained_exp_team"    
##  [97] "rec_yards_gained_exp_team"      "rush_yards_gained_exp_team"    
##  [99] "pass_touchdown_team"            "rec_touchdown_team"            
## [101] "rush_touchdown_team"            "pass_touchdown_exp_team"       
## [103] "rec_touchdown_exp_team"         "rush_touchdown_exp_team"       
## [105] "pass_two_point_conv_team"       "rec_two_point_conv_team"       
## [107] "rush_two_point_conv_team"       "pass_two_point_conv_exp_team"  
## [109] "rec_two_point_conv_exp_team"    "rush_two_point_conv_exp_team"  
## [111] "pass_first_down_team"           "rec_first_down_team"           
## [113] "rush_first_down_team"           "pass_first_down_exp_team"      
## [115] "rec_first_down_exp_team"        "rush_first_down_exp_team"      
## [117] "pass_interception_team"         "rec_interception_team"         
## [119] "pass_interception_exp_team"     "rec_interception_exp_team"     
## [121] "rec_fumble_lost_team"           "rush_fumble_lost_team"         
## [123] "pass_fantasy_points_exp_team"   "rec_fantasy_points_exp_team"   
## [125] "rush_fantasy_points_exp_team"   "pass_fantasy_points_team"      
## [127] "rec_fantasy_points_team"        "rush_fantasy_points_team"      
## [129] "total_yards_gained_team"        "total_yards_gained_exp_team"   
## [131] "total_touchdown_team"           "total_touchdown_exp_team"      
## [133] "total_first_down_team"          "total_first_down_exp_team"     
## [135] "total_fantasy_points_team"      "total_fantasy_points_exp_team" 
## [137] "pass_completions_diff_team"     "receptions_diff_team"          
## [139] "pass_yards_gained_diff_team"    "rec_yards_gained_diff_team"    
## [141] "rush_yards_gained_diff_team"    "pass_touchdown_diff_team"      
## [143] "rec_touchdown_diff_team"        "rush_touchdown_diff_team"      
## [145] "pass_two_point_conv_diff_team"  "rec_two_point_conv_diff_team"  
## [147] "rush_two_point_conv_diff_team"  "pass_first_down_diff_team"     
## [149] "rec_first_down_diff_team"       "rush_first_down_diff_team"     
## [151] "pass_interception_diff_team"    "rec_interception_diff_team"    
## [153] "pass_fantasy_points_diff_team"  "rec_fantasy_points_diff_team"  
## [155] "rush_fantasy_points_diff_team"  "total_yards_gained_diff_team"  
## [157] "total_touchdown_diff_team"      "total_first_down_diff_team"    
## [159] "total_fantasy_points_diff_team"



Best and Worst Performances by Individual Players (2006 - 2021)


Best Single Game Performances

FF_Opportunity_2006_2021 %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Single Game Performances

FF_Opportunity_2006_2021 %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best Regular Season Average Performances in 8+ Games by Season

FF_Opportunity_2006_2021 %>% 
filter(week <= 17) %>% 
group_by(full_name, season, position) %>% 
summarise(
    avg_fantasy_points = mean(total_fantasy_points),
    games_played = n_distinct(week)
) %>% 
filter(games_played >= 8) %>% 
arrange(desc(avg_fantasy_points)) %>% 
drop_na() %>% 
head(100) %>% 
paged_table()


Worst Regular Season Average Performances in 8+ Games by Season

FF_Opportunity_2006_2021 %>% 
filter(week <= 17) %>% 
group_by(full_name, season, position) %>% 
summarise(
    avg_fantasy_points = mean(total_fantasy_points),
    games_played = n_distinct(week)
) %>% 
filter(games_played >= 8) %>% 
arrange(avg_fantasy_points) %>% 
drop_na() %>% 
head(100) %>% 
paged_table()


Best Regular Season Single Game Performances in 2021

FF_Opportunity_2006_2021 %>%
filter(
    season == 2021,
    week <= 17
) %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Regular Season Single Game Performances in 2021

FF_Opportunity_2006_2021 %>% 
filter(
    season == 2021,
    week <= 17
) %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best Regular Season Single Game Performance by QB

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'QB'
) %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Regular Season Single Game Performance by QB

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'QB'
) %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best Regular Season Single Game Performance by RB

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'RB'
) %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Regular Season Single Game Performance by RB

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'RB'
) %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best Regular Season Single Game Performance by WR

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'WR'
) %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Regular Season Single Game Performance by WR

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'WR'
) %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best Regular Season Single Game Performance by TE

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'TE'
) %>% 
arrange(desc(total_fantasy_points)) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Worst Regular Season Single Game Performance by TE

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    position == 'TE'
) %>% 
arrange(total_fantasy_points) %>% 
select(
    full_name,
    game_id,
    position,
    total_fantasy_points
) %>% 
head(100) %>% 
paged_table()


Best / Worst Single Game Performance by Position Over Time

Min_Max_Position <-
    FF_Opportunity_2006_2021 %>% 
    filter(
        position %in% c('QB', 'RB', 'WR', 'TE')
    ) %>% 
    group_by(season, position) %>% 
    summarise(
        max_points = max(total_fantasy_points),
        min_points = min(total_fantasy_points)
    )


Min_Max_Position %>% 
ggplot(aes(x = season, y = max_points, color = position)) + 
stat_smooth(method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Position') +
ggtitle('Most Fantasy Points by Individual Player') +
xlab(paste('\n', 'Season')) +
ylab(paste('Fantasy Points', '\n'))


Min_Max_Position %>% 
ggplot(aes(x = season, y = min_points, color = position)) + 
stat_smooth(method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Position') +
ggtitle('Fewest Fantasy Points by Individual Player') +
xlab(paste('\n', 'Season')) +
ylab(paste('Fantasy Points', '\n'))



Individual Team Regular Season Fantasy Point Scoring (2006 - 2021)

FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'NO',
        'NE',
        'GB',
        'LAC',
        'DAL'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 
    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Highest Mean Teams)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))


FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'NYJ',
        'CLE',
        'JAX',
        'BUF',
        'TEN'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 
    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Lowest Mean Teams)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))


FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'KC',   
        'DEN',  
        'TB',
        'LA',   
        'LV'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 

    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Highest Variance Teams)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))


FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'DEN',
        'KC',
        'TB',   
        'NO',
        'BUF'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 
    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Largest Range Teams)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))


FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'TB',           
        'DAL',          
        'LAC',      
        'KC',       
        'LA'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 

    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Highest Teams in 2021)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))


FF_Opportunity_2006_2021 %>% 
filter(
    week <= 17,
    posteam %in% c(
        'NYG',          
        'HOU',          
        'JAX',      
        'CAR',      
        'CHI'
    )
) %>% 
group_by(week, season, posteam) %>% 
summarise(
    game_points = sum(total_fantasy_points)
) %>% 
group_by(season, posteam) %>% 
summarise(
    avg_game_points = mean(game_points)
) %>% 
    
ggplot(aes(x = season, y = avg_game_points, color = posteam)) +
stat_smooth(aes(x = season, y = avg_game_points), method = 'lm', formula = y ~ poly(x, 5), se = FALSE) +
theme_bw() +
scale_x_continuous(breaks = pretty_breaks(n = 10)) +
scale_color_gdocs('Team') +
ggtitle('Mean Fantasy Points Per Game (5 Lowest Teams in 2021)') +
xlab(paste('\n', 'Season')) +
ylab(paste('Mean Fantasy Points / Game', '\n'))