Introduction

Kicking in the NFL is a huge part of the game. Field goals are the main job that a kicker has, other ones include kickoffs and extra points. Kickers often score the most points of any player on a team, therefore the difference between a good and great one cannot be understated.

Description of Project

There are many ways to analyze what makes a “good” kicker. I personally value a kicker who is more consistent from shorter distances, meaning that if my team gets inside the 35 yard line, it’ll be automatic points, over a kicker who will occasionally bail out my offense with a long field goal. The stat that I created to reflect this takes kickers kicking percentages from four distances: inside forty yards, which is weighted as 2, from forty to fifty yards weighted as 1.5, from fifty to sixty yards weighted as 1.25 and kicks from sixty plus yards are weighted as 1. This values very heavily kicks inside forty yards. This means that if the offence can get the ball to the thirty yard line, making kicks at a higher clip will result in a higher total.

Data Visualization

I created a graph, organized by year, though any kicker that did not have more than 50 attempts over the three year span was not considered.

setwd("/Users/smesaros/Desktop/IS470")

library(data.table)
library(dplyr)
library(ggplot2)
library(scales)
library(tidytext)
# Read in and merge four data files

my_df1 <- fread("Data/NFLBDB2022/plays.csv")
my_df2 <- fread("Data/NFLBDB2022/players.csv")
my_df3 <- fread("Data/NFLBDB2022/games.csv")
my_df4 <- fread("Data/NFLBDB2022/PFFScoutingData.csv")



df <- left_join(my_df1, my_df2, by = c("kickerId" = "nflId"))
df <- left_join(df,     my_df3, by = c("gameId"))
df <- left_join(df,     my_df4, by = c("gameId", "playId"))

rm(my_df1)
rm(my_df2)
rm(my_df3)
rm(my_df4)

fieldgoal_df <- df%>%
  filter(specialTeamsPlayType == "Field Goal")%>%
  group_by(kickerId)%>%
  arrange(kickerId)%>%
  
  mutate(inside_forty = ifelse(kickLength < 39, 1,0))%>%
  filter(!is.na(inside_forty))%>%
  mutate(made_inside_forty = ifelse(specialTeamsResult == "Kick Attempt Good" & inside_forty == 1, 1, 0))%>%
  mutate(kicking_percent_inside_forty = sum(made_inside_forty)/sum(inside_forty))%>%
  
  mutate(forty_to_fifty = ifelse(between(kickLength,40,49),1,0))%>%
  mutate(made_forty_to_fifty = ifelse(specialTeamsResult == "Kick Attempt Good" & forty_to_fifty == 1,1,0))%>%
  mutate(kicking_percent_forty_to_fifty = sum(made_forty_to_fifty)/sum(forty_to_fifty))%>%
  
  mutate(fifty_to_sixty = ifelse(between(kickLength,50,59),1,0))%>%
  mutate(fifty_to_sixty, made_fifty_to_sixty = ifelse(specialTeamsResult == "Kick Attempt Good" & fifty_to_sixty == 1,1,0))%>%
  mutate(kicking_percent_fifty_to_sixty = sum(made_fifty_to_sixty)/sum(fifty_to_sixty))%>%
  
  mutate(sixty_plus = ifelse(kickLength >= 60 ,1,0))%>%
  mutate(sixty_plus, made_sixty_plus = ifelse(specialTeamsResult == "Kick Attempt Good" & sixty_plus == 1,1,0))%>%
  mutate(kicking_percent_sixty_plus = sum(made_sixty_plus)/sum(sixty_plus))%>%
  
  mutate(final_sixty_plus = ifelse(is.integer(kicking_percent_sixty_plus), kicking_percent_sixty_plus, 0))%>%
  
  mutate(total_kicking = (2 * (kicking_percent_inside_forty)) + (1.5 * (kicking_percent_forty_to_fifty))
         + (1.25 * (kicking_percent_fifty_to_sixty)) + (final_sixty_plus))%>%
  filter(!is.na(total_kicking))%>%
  mutate(kick_attempts = sum(inside_forty) + sum(forty_to_fifty) + sum(fifty_to_sixty) + sum(sixty_plus))%>%
  filter(kick_attempts > 51)%>%
  
  mutate(seasons = "2018-2020")%>%
  
  data.frame()
ggplot(data = fieldgoal_df, aes(x = reorder_within(displayName, -total_kicking, seasons), y = total_kicking, fill = total_kicking))+ 
    geom_bar(stat = "identity", position = "dodge")+
    labs(x = "Kicker", y = "Total Kicking", title = "Total Kicking for Kickers from 2018-2020")+
    geom_text(aes(label = (round(total_kicking, digits = 3))), vjust = 1.25, size = 2.3)+
    scale_fill_continuous(breaks = seq(.1,1,0.2),
                          limits = c(min(fieldgoal_df$total_kicking),max(fieldgoal_df$total_kicking)),
                          labels = paste0(100*seq(.1,1,0.2)),
                          low = "red",
                          high = "forestgreen")+
    theme(plot.title = element_text(hjust = 0.50))+
    scale_y_continuous(limits = c(0, max(fieldgoal_df$total_kicking)))+
    scale_x_reordered()+
    facet_wrap(~seasons, scales = "free", ncol = 1)+
    theme(axis.text.x = element_text(angle = 20, size = 7.0))

Conclusion

The kickers which are often considered among the best in the NFL were at the top of the list in total kicking. This is be because teams also value consistency from close over a semi-consistent kicker who can hit kicks from fifty plus yards.