Introduction

I created a weighted accuracy metric (WAM) for kickers from the 2018 - 2020 seasons based on field goal attempts. The goal is to produce a visualization that depicts who the some of the best kickers in the NFL based on the WAM system.

Description of Project

For this assignment, I wanted to create a composite ranking system for kickers via a weight-system. For each field goal attempt taken, the kick will go into one of three buckets depending on the distance of the attempt. From this separation of field goal attempts, new columns will be able to collect the makes and misses for each of the three distance buckets. Once the kicks have been sorted out by bucket and make/miss, each individual kicker will have all of his kick sorted together, produce three accuracy percentages (one for each of the three buckets); those three percentages will be multiplied by their corresponding weights, as seen below.

WAM System Breakdown: Weighting Field Goal Attempts

Any field goal attempt less than 35 yards - weighs 20% of weighted accuracy metric. Any field goal attempt greater than 34 yards and less than 50 - weighs 35% of weighted accuracy metric. Any field goal attempt lower than 34 yards - weighs 45% of weighted accuracy metric. With a strong emphasis on making any field goals from further distances, scores will be consider the further distance intervals with more consideration compares to any field goal attempts from 35 yards.

Data Visualization: The WAM Metric

Reflecting on the visualization this program produced, I believe that weighted accuracy metric offers a good amount of insight as to who are some of the best kickers have been in recent names. Notable names, such as Younghoe Koo (ATL), Justin Tucker (BAL), Ryan Succop (TEN/TB), and more are featured among the top names through this scoring metric. The best kickers in these ranking have scored between 85% - 95% weighted accuracy; one would be able to see in the data that these kickers make majority of kicks beyond the 35 yard line. The gradient filling of the bars represents the number of field goal attempts that each kicker had over the three seasons. The lighter the shade of blue, the more field goals the kicker attempted.

setwd("U:/")  

library(ggplot2)
library(data.table)
library(dplyr)
library(scales)
library(knitr)

my_df1 <- fread("U:/IS470/Data/NFLBDB2022/plays.csv")
my_df2 <- fread("U:/IS470/Data/NFLBDB2022/players.csv")
my_df3 <- fread("U:/IS470/Data/NFLBDB2022/games.csv")

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

kicker_df <- df %>%
  filter(specialTeamsPlayType == "Field Goal") %>%
  filter(specialTeamsResult == "Kick Attempt Good" | specialTeamsResult =="Kick Attempt No Good") %>% 
  select(kickerId, displayName, season, week, gameDate, gameId, playId, quarter, gameClock, specialTeamsPlayType, specialTeamsResult, playResult, kickLength) %>%
  data.frame()

accuracy_buckets_df <- kicker_df %>%
  filter(specialTeamsResult == "Kick Attempt Good" | specialTeamsResult == "Kick Attempt No Good") %>%
  mutate(kickAttemptBucket = ifelse (kickLength < 35, 1, (ifelse (kickLength > 49, 3, 2))),
         succeed35 = ifelse(specialTeamsResult == "Kick Attempt Good" & kickAttemptBucket == 1, 1,0),
         fail35 = ifelse(specialTeamsResult == "Kick Attempt No Good" & kickAttemptBucket == 1, 1,0),
         succeed_between = ifelse(specialTeamsResult == "Kick Attempt Good" & kickAttemptBucket == 2, 1,0),
         fail_between = ifelse(specialTeamsResult == "Kick Attempt No Good" & kickAttemptBucket == 2, 1,0),
         succeed50 = ifelse(specialTeamsResult == "Kick Attempt Good" & kickAttemptBucket == 3, 1,0),
         fail50 = ifelse(specialTeamsResult == "Kick Attempt No Good" & kickAttemptBucket == 3, 1,0)) %>%
  group_by(displayName) %>%
  summarise(acc1 = sum(succeed35) / ( sum(fail35) + sum(succeed35) ),
            acc2 = sum(succeed_between) / ( sum(fail_between) + sum(succeed_between) ),
            acc3 = sum(succeed50) / ( sum(fail50) + sum(succeed50) ),
            kick_count = n(),
            .groups = 'keep') %>%
  mutate(wad_acc = (acc1 * 0.2) + (acc2 * 0.35) + (acc3 * 0.45)) %>%
  filter(kick_count >= 40) %>%
  data.frame()

Data Visualization : WAM System Ranking of NFL Kickers

# create a bump chart
ggplot(data = accuracy_buckets_df, aes(x = wad_acc, y = reorder(displayName, wad_acc), fill = kick_count)) +
  geom_bar(stat = "identity") + 
  labs(x = "Percentage of Weighted Kick Attempts Made", y = "Kicker Name", 
       title = "WAM System Ranking of NFL Kickers by Field Goals Attempts", fill = "Field Goals Attempted") +
  geom_text(aes(label = label_percent(accuracy = 1L) (wad_acc)), hjust = -0.2 ) +
  scale_x_continuous(labels = scales::percent) +
  theme(plot.title = element_text(hjust = 0.5))

Conclusion

For further research, coding, and visualizing, I would like to implement extra points into a similar program to capture more data on kickers. Looking at how far kickers kick the ball back towards the receiving team’s end zone would be another area of interest, as the punt does not do this. This would be another great way to rank the best kicker in the NFL. Grading ‘clutchness’ would be quite interesting to research and quantify as well.