# this was to figure out how to create chunks
library(ggplot2)
library(ggalt)
library(ggforce)
library(hms)
library(gganimate)
library(data.table)
library(dplyr)
library(RColorBrewer)
library(nflfastR)
library(ggimage)
library(png)
library(gifski)
#Here is my code
In this project I decided to create a metric I called “Total Kicker Value” to measure the value that kickers bring to their teams. I assigned point values to different lengths of field goals in the categories of easy (under 25 yards), Medium (between 25 and 50 yards), and Hard (Over 50 Yards) as well as extra points. I did this because a long field goal is more valuable to a team than a short one in terms of points over expected. I assigned a value of 1 to easy field goals, a value of 1.25 to medium field goals, a value of 1.5 to long field goals and a value of .1 to extra points (as the expected points added vs going for the two point conversion often isn’t that high). I then took these key values and multiplied them by their respective difficulty category accuracy and added them. I used this value (total_kicker value = easyAccuracy + (medAccuracy * 1.25) +(hardAccuracy 1.5) + (ExtraPointAccuracy .1)), to compare the different kickers.
I first created a joint data table of players and plays by linking the kickerId to the nflId in the left-join. I then filtered the table for plays that were field goals and extra points respectively and further filtered field goals into 6 data frames to count instances of, easy FG made, easy FG missed, medium FG made, medium FG missed, hard FG made, and hard FG missed. I further filtered extra points into instances of missed and made extra points. I then joined all of these tables into one table and mutated new columns calculating the accuracy % for easy, medium, and hard field goals and extra points. I did this to be able to compare kickers that kicked different numbers of field goals and extra points accurately. I then multiplied these %s by their respective values (easy = 1, med = 1.25, hard = 1.5, XP = .1) and added them together to find the kickers with the best total values.
My visualization is a bar chart showing which kickers had the highest total kicker value for their team. The more green the fill of the bars are the higher the total kicker value. Additionally the bar chart is arranged top to bottom in terms of decending total value score. I also only presented the top 32 kickers (1 for each team) in the bar chart for ease of reading.
#remmeber to set the wd to where I need it to be
setwd("C:/New Data")
file.path(getwd(),"Data/NFLBDB2022")
## [1] "C:/New Data/Data/NFLBDB2022"
library(ggplot2)
library(data.table)
library(dplyr)
library(scales)
library(tidytext)
library(RColorBrewer)
library(kableExtra)
library(ggalt)
library(ggforce)
library(hms)
library(gganimate)
library(data.table)
library(dplyr)
library(RColorBrewer)
library(nflfastR)
library(ggimage)
library(png)
library(gifski)
players <- fread("Data/NFLBDB2022/players.csv")
df_plays <- fread("Data/NFLBDB2022/plays.csv")
df_games <-fread("Data/NFLBDB2022/games.csv")
#Here I am just going to clean up some of the data to take just the field goals and extra points out of the data
df_extra_points <- df_plays %>%
left_join(players, by = c("kickerId" = "nflId")) %>%
select(kickerId,kickLength,specialTeamsPlayType, specialTeamsResult, displayName)%>%
filter(specialTeamsPlayType %in% c("Extra Point")) %>%
filter(! is.na(kickerId)) %>%
group_by(kickerId) %>%
arrange(kickerId)%>%
data.frame()
#Count made extra points
count_by_kicker_madeXp <- df_extra_points %>%
filter(specialTeamsResult == "Kick Attempt Good") %>%
group_by(kickerId,displayName) %>%
summarise(countMadeXp = n(), .groups = "keep")%>%
data.frame()
#Counts XP Missed by each Kicker
count_by_kicker_missXp <- df_extra_points %>%
filter(specialTeamsResult != "Kick Attempt Good") %>%
group_by(kickerId,displayName) %>%
summarise(countMissXp = n(), .groups = "keep")%>%
data.frame()
#Count missed extra points
#Field goals data
df_kicks <- df_plays %>%
left_join(players, by = c("kickerId" = "nflId")) %>%
select(kickerId,kickLength,specialTeamsPlayType, specialTeamsResult, displayName)%>%
filter(specialTeamsPlayType %in% c("Field Goal")) %>%
filter(! is.na(kickerId)) %>%
group_by(kickerId) %>%
arrange(kickerId)%>%
data.frame() #%>% print()
#Counts the Extra Points made by players
#Counts field goals made by each kicker
count_by_kicker_made_total <- df_kicks %>%
filter(specialTeamsResult == "Kick Attempt Good") %>%
group_by(kickerId,displayName) %>%
summarise(countMade = n(), .groups = "keep")%>%
data.frame()
#Counts Field Goals Missed by each Kicker
count_by_kicker_miss_total <- df_kicks %>%
filter(specialTeamsResult != "Kick Attempt Good") %>%
group_by(kickerId,displayName) %>%
summarise(countMiss = n(), .groups = "keep")%>%
data.frame()
#Counts made field goals from 10-25 yards
count_by_kicker_made_easy <- df_kicks %>%
filter(specialTeamsResult == "Kick Attempt Good") %>%
filter(kickLength <= 25) %>%
group_by(kickerId,displayName) %>%
summarise(countEasy = n(), .groups = "keep")%>%
data.frame()
#Counts missed easy field goals
count_by_kicker_miss_easy <- df_kicks %>%
filter(specialTeamsResult != "Kick Attempt Good") %>%
filter(kickLength <= 25) %>%
group_by(kickerId,displayName) %>%
summarise(countEasyMiss = n(), .groups = "keep")%>%
data.frame()
#Counts made intermediate field goals (25-50 yards)
count_by_kicker_made_med <- df_kicks %>%
filter(specialTeamsResult == "Kick Attempt Good") %>%
filter(kickLength >= 25 & kickLength <= 50) %>%
group_by(kickerId,displayName) %>%
summarise(countMed = n(), .groups = "keep")%>%
data.frame()
#Counts missed intermediate field goals
count_by_kicker_miss_med <- df_kicks %>%
filter(specialTeamsResult != "Kick Attempt Good") %>%
filter(kickLength >= 25 & kickLength <= 50) %>%
group_by(kickerId,displayName) %>%
summarise(countMedMiss = n(), .groups = "keep")%>%
data.frame()
#Counts made hard field goals
count_by_kicker_made_hard <- df_kicks %>%
filter(specialTeamsResult == "Kick Attempt Good") %>%
filter(kickLength >= 50) %>%
group_by(kickerId,displayName) %>%
summarise(countHard = n(), .groups = "keep")%>%
data.frame()
#Counts miss hard field goals
count_by_kicker_miss_hard <- df_kicks %>%
filter(specialTeamsResult != "Kick Attempt Good") %>%
filter(kickLength >= 50) %>%
group_by(kickerId,displayName) %>%
summarise(countHardMiss = n(), .groups = "keep")%>%
data.frame()
#Join together all of the frames
df_field_goal_counts <- count_by_kicker_made_total %>%
left_join(count_by_kicker_miss_total, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_made_easy, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_made_med, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_made_hard, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_miss_easy, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_miss_med, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_miss_hard, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_madeXp, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
left_join(count_by_kicker_missXp, by = c("kickerId" = "kickerId", "displayName" = "displayName")) %>%
select(kickerId,displayName, countMade, countMiss, countEasy, countMed, countHard, countEasyMiss, countMedMiss, countHardMiss, countMadeXp,countMissXp)%>%
#replace zero values
mutate(countMade = ifelse(is.na(countMade), 0, countMade)) %>%
mutate(countMiss = ifelse(is.na(countMiss), 0, countMiss)) %>%
mutate(countEasy = ifelse(is.na(countEasy), 0, countEasy)) %>%
mutate(countMed = ifelse(is.na(countMed), 0, countMed)) %>%
mutate(countHard = ifelse(is.na(countHard), 0, countHard)) %>%
mutate(countEasyMiss = ifelse(is.na(countEasyMiss), 0, countEasyMiss)) %>%
mutate(countMedMiss = ifelse(is.na(countMedMiss), 0, countMedMiss)) %>%
mutate(countHardMiss = ifelse(is.na(countHardMiss), 0, countHardMiss)) %>%
mutate(countMadeXp = ifelse(is.na(countMadeXp), 0, countMadeXp)) %>%
mutate(countMissXp = ifelse(is.na(countMissXp), 0, countMissXp)) %>%
mutate(totalAccuracy = countMade/(countMiss+countMade),
easyAccuracy = countEasy/(countEasy + countEasyMiss),
medAccuracy =countMed/(countMed + countMedMiss),
hardAccuracy = countHard/(countHard +countHardMiss),
extraPointAccuracy = countMadeXp/ (countMadeXp + countMissXp))%>%
mutate(easyAccuracy = ifelse(is.nan(easyAccuracy), 0, easyAccuracy))%>%
mutate(medAccuracy = ifelse(is.nan(medAccuracy), 0, medAccuracy))%>%
mutate(hardAccuracy = ifelse(is.nan(hardAccuracy), 0, hardAccuracy))%>%
mutate(extraPointAccuracy = ifelse(is.nan(extraPointAccuracy), 0, extraPointAccuracy))%>%
mutate(total_kicker_value = (easyAccuracy + (medAccuracy * 1.25) + (hardAccuracy * 1.5) + (extraPointAccuracy * .25)))%>%
arrange(-total_kicker_value)%>%
head(32)%>%
data.frame()
# horizontal bar chart
ggplot(data = df_field_goal_counts, aes(x = reorder(displayName, total_kicker_value), y = total_kicker_value, fill = total_kicker_value)) +
geom_bar(stat = "identity") +
labs(x = "Kickers", y = "Total Kicker Value", title = "Total Kicker values of kickers included in Data") +
coord_flip() +
geom_text(aes(label = label_value(total_kicker_value)), hjust = -0.2,) +
scale_fill_continuous(breaks = seq(3,4),
limits = c(3,4),
low = "red",
high ="limegreen" ) #+
The best kickers in the NFL ranked by Total kicker Value. Younghoe Koo is number 1.
#theme(plot.title = element_text(hjust = 0.5))
I found that the best kicker by my metric was Younghoe Koo. He was followed by Josh Lambo and Mike Nugent. This surprised me as I had figured that Justin Tucker would be found to be the best kicker in the NFL and he ended up 9th in my metric. I believe that the reason my ranking had him ranked so low was the fact that he attempted a good many more difficult field goals than the stat leaders. This dragged his total score down as despite having made more total long field goals, his score was dragged down by also having missed some of his attempted longer field goals. A kicker can get lucky go 1 for 1 in my metric on long field goals and end up with a better score than someone who goes 9/10. This is something I would have liked to adjust for if I had the time and is something I would definitely consider weighing in the future for a similar exercise.
knitr::include_graphics("C:/New Data")
Courtesy of your favorite IT professor