In the world of the NFL, the special teams, particularly kickers hold a very important position to decide about the outcomes of games. Their accuracies in kicks, the success rate with connection to the field goals, and the performance under pressure dictate many times at what turning point a team emerges for victory or defeat. The following report analyzes the performances of NFL kickers through a close study of field goal attempts and success rates over a given period of time. We aim to understand how many field goals were made and at what success rate to identify the most consistent kickers who have delivered the best results for their teams.
This project utilizes NFL data from four datasets: games, plays, players, and pffScoutingData. This large data was filtered in order to focus our target on Field Goals. This calculation of different performance metrics for every kicker was performed while keeping in mind important parameters like a total field goal attempt, total number of kicks made. Cleaning of the final dataset in such a way that we can visualize them using various plots. Visualize the top 25 kickers ranked by their field goal success rate along with their total field goals made and respective extra point conversion rates.
We generated two visualizations to illustrate the data and key findings:
Top 25 NFL Kickers by Success Rate: This table shows the top 25 kickers based on their field goal success rate. It gives a quick snapshot of which kickers were most accurate. Top 25 Kickers by Field Goals Made: A horizontal bar chart showing the top 20 kickers by the number of field goals made. The chart is color-coded by success rate, with kickers with a higher success rate displayed in green and those with lower rates in red. This visualization emphasizes not just accuracy, but volume, highlighting the kickers who were both heavily relied upon by their teams and consistently successful.
setwd("/Users/davidbrown23/Data/NFLBDB2022/NFL2022")
getwd()=='/Users/davidbrown23/Data/NFLBDB2022/NFL2022'
## [1] TRUE
## Load Packages
library(ggplot2)
library(data.table)
library(dplyr)
library(scales)
library(tidytext)
library(RColorBrewer)
library(kableExtra)
library(knitr)
# Load the data
games <- fread("Data/NFLBDB2022/games.csv")
plays <- fread("Data/NFLBDB2022/plays.csv")
players <- fread("Data/NFLBDB2022/players.csv")
pff <- fread("Data/NFLBDB2022/pffScoutingData.csv")
colnames(plays)
## [1] "gameId" "playId" "playDescription"
## [4] "quarter" "down" "yardsToGo"
## [7] "possessionTeam" "specialTeamsPlayType" "specialTeamsResult"
## [10] "kickerId" "returnerId" "kickBlockerId"
## [13] "yardlineSide" "yardlineNumber" "gameClock"
## [16] "penaltyCodes" "penaltyJerseyNumbers" "penaltyYards"
## [19] "preSnapHomeScore" "preSnapVisitorScore" "passResult"
## [22] "kickLength" "kickReturnYardage" "playResult"
## [25] "absoluteYardlineNumber"
colnames(players)
## [1] "nflId" "height" "weight" "birthDate" "collegeName"
## [6] "Position" "displayName"
colnames(games)
## [1] "gameId" "season" "week" "gameDate"
## [5] "gameTimeEastern" "homeTeamAbbr" "visitorTeamAbbr"
colnames(pff)
## [1] "gameId" "playId"
## [3] "snapDetail" "snapTime"
## [5] "operationTime" "hangTime"
## [7] "kickType" "kickDirectionIntended"
## [9] "kickDirectionActual" "returnDirectionIntended"
## [11] "returnDirectionActual" "missedTackler"
## [13] "assistTackler" "tackler"
## [15] "kickoffReturnFormation" "gunners"
## [17] "puntRushers" "specialTeamsSafeties"
## [19] "vises" "kickContactType"
# Merging datasets
df_merged <- plays %>%
left_join(games, by = "gameId") %>%
left_join(pff, by = c("gameId", "playId")) %>%
left_join(players, by = c("kickerId" = "nflId"))
# Focus on field goal plays
field_goal_plays <- df_merged %>%
filter(specialTeamsPlayType == "Field Goal")
# Count outcomes of field goal plays
table(field_goal_plays$specialTeamsResult)
##
## Blocked Kick Attempt Downed Kick Attempt Good
## 37 1 2218
## Kick Attempt No Good Non-Special Teams Result Out of Bounds
## 386 14 1
# Group by kicker and summarize their performance
kicker_stats <- field_goal_plays %>%
group_by(displayName, possessionTeam) %>%
summarise(
attempts = n(),
successful_kicks = sum(specialTeamsResult == "Kick Attempt Good"),
success_rate = successful_kicks / attempts * 100
) %>%
filter(attempts > 20) %>%
arrange(-success_rate)
# Show top 25 kickers by success rate
knitr::kable(head(kicker_stats, 25), caption = 'Top 25 NFL Kickers by Success Rate') %>%
kable_styling(bootstrap_options = c("striped", "hover"))
| displayName | possessionTeam | attempts | successful_kicks | success_rate |
|---|---|---|---|---|
| Graham Gano | NYG | 30 | 29 | 96.66667 |
| Josh Lambo | JAX | 57 | 54 | 94.73684 |
| Daniel Carlson | LV | 33 | 31 | 93.93939 |
| Cairo Santos | CHI | 29 | 27 | 93.10345 |
| Justin Tucker | BAL | 94 | 87 | 92.55319 |
| Jason Myers | NYJ | 36 | 33 | 91.66667 |
| Younghoe Koo | ATL | 57 | 52 | 91.22807 |
| Jason Myers | SEA | 44 | 40 | 90.90909 |
| Harrison Butker | KC | 85 | 77 | 90.58824 |
| Nick Folk | NE | 42 | 38 | 90.47619 |
| Ryan Succop | TB | 29 | 26 | 89.65517 |
| Wil Lutz | NO | 86 | 77 | 89.53488 |
| Mason Crosby | GB | 71 | 63 | 88.73239 |
| Aldrick Rosas | NYG | 44 | 39 | 88.63636 |
| Chris Boswell | PIT | 63 | 55 | 87.30159 |
| Rodrigo Blankenship | IND | 36 | 31 | 86.11111 |
| Brandon McManus | DEN | 84 | 72 | 85.71429 |
| Cody Parkey | CLE | 21 | 18 | 85.71429 |
| Randy Bullock | CIN | 77 | 66 | 85.71429 |
| Jason Sanders | MIA | 83 | 71 | 85.54217 |
| Dustin Hopkins | WAS | 86 | 73 | 84.88372 |
| Stephen Gostkowski | NE | 39 | 33 | 84.61538 |
| Ka’imi Fairbairn | HOU | 96 | 81 | 84.37500 |
| Robbie Gould | SF | 79 | 66 | 83.54430 |
| Eddy Pineiro | CHI | 24 | 20 | 83.33333 |
# Visualization 1: A graph that shows Number of Attempts vs. Success Rate
# horizontal bar chart
# Group by kicker and calculate successful field goals (Field Goals Made)
kicker_stats <- field_goal_plays %>%
group_by(displayName, possessionTeam) %>%
summarise(
attempts = n(),
successful_kicks = sum(specialTeamsResult == "Kick Attempt Good"),
success_rate = successful_kicks / attempts * 100
) %>%
filter(attempts > 20) %>%
arrange(-successful_kicks)
# Filter for top 20 kickers by field goals made (successful_kicks)
top_kickers <- kicker_stats %>%
arrange(-successful_kicks) %>%
head(25)
# Plot for Field Goals Made (Successful Kicks)
ggplot(top_kickers, aes(x = reorder(displayName, successful_kicks), y = successful_kicks, fill = success_rate)) +
geom_bar(stat = "identity", width = 0.8, position = position_dodge2(preserve = "single")) +
labs(x = "Kicker", y = "Field Goals Made", title = "Top 25 Kickers by Field Goals Made") +
coord_flip() +
geom_text(aes(label = paste0(successful_kicks, " FGs Made")), hjust = -0.2, size = 3.5) +
scale_fill_continuous(low = "red", high = "green") +
theme_minimal() +
theme(
axis.text.y = element_text(size = 9, face = "bold"),
axis.text.x = element_text(size = 10),
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank()
) +
scale_y_continuous(expand = c(0.05, 0))
This result shows that the elite NFL kickers are reliable and steady performers; the proportions of field goals they had converted are high, as also is the number of field goals they converted. In such cases, its clear from the data that many of them had not only a large number of attempts but also, out of those, a very high percentage, to show just how much they meant to their teams. These charts provide some ideas on volume and performance balance in field goals. Consistently, guys like Justin Tucker and Harrison Butker have been performing over an extremely high number of attempts. Certain teams or fans may know that a kicker is always great under duress and is a good game changer.