setwd("C:/Users/pptallon/Dropbox/G/Teaching/Loyola College/IS 470 Sports Analytics/Fall 2026/")

source("https://raw.githubusercontent.com/ptallon/SportsAnalytics_Fall2026/refs/heads/main/SharedCode.R")

load_packages(c("data.table", "dplyr", "ggplot2", "tidytext", "scales"))

y1 <- fread("NFLBDB2022/tracking2018.csv")
y2 <- fread("NFLBDB2022/tracking2019.csv")
y3 <- fread("NFLBDB2022/tracking2020.csv")

trellis_df <- rbind(y1, y2, y3)
rm(y1, y2, y3)

plays   <- fread("NFLBDB2022/plays.csv")
players <- fread("NFLBDB2022/players.csv")
games   <-  fread("NFLBDB2022/games.csv")

plays_df <- left_join(plays, players, by = c("kickerId" = "nflId"))
plays_df <- left_join(plays_df, games, by = c("gameId"))

kicker_df <- plays_df |>
  select(displayName, season, kickLength, 
         specialTeamsPlayType, specialTeamsResult) |>
  filter(specialTeamsPlayType == "Field Goal",
         specialTeamsResult != "Non-Special Teams Result") |>
  group_by(displayName, season) |>
  summarise(Attempts = n(), 
            Kicks_made = sum(specialTeamsResult == "Kick Attempt Good"),
            Kicks_missed = sum(specialTeamsResult == "Kick Attempt No Good"),            
            Accuracy = percent(Kicks_made / Attempts, accuracy = 0.1),            
            #Min_length = min(kickLength, na.rm = T),
            .groups = "keep") |>
  group_by(season) |>
  mutate(year_rank = min_rank(desc(Accuracy))) %>%
  ungroup() |>
  group_by(displayName) |>
  mutate(all_seasons = percent(sum(Kicks_made) / sum(Attempts), accuracy = 0.1),
         seasons_played = n()) |>
  ungroup() |>
  filter(seasons_played == 3) |>
  mutate(Rank = dense_rank(desc(all_seasons))) |>
  arrange(Rank, season) |>
  data.frame()  

kicker_df$Accuracy <- as.numeric(sub("%", "", kicker_df$Accuracy))

ggplot(kicker_df |> filter(Rank <= 10)      , 
            aes(x = displayName, y = Accuracy, fill = factor(season))) +
  geom_col(position = "dodge") +
  geom_text(aes(label = percent(Accuracy/100, accuracy = 1)),
            position = position_dodge(width=0.9),
            vjust = -0.4,
            hjust = 0.5,
            size = 2.3
  ) +
  scale_x_discrete(labels = function(x) gsub(" ", "\n", x) ) +
  labs( x = "Kicker Name", 
        y = "Accuracy (Good Kicks as a Percentage of All Kicks)",
        fill = "Season",
        title = "Top 10 NFL Kickers in 2018-2020"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

# Keep top 10 kickers from each season
top10 <- kicker_df %>%
  filter(Attempts >= mean(Attempts)) %>%
  group_by(season) %>%
  mutate(season_rank = min_rank(desc(Accuracy))) %>%
  ungroup() %>%
  filter(season_rank <= 10) %>%
  data.frame()

ggplot(top10,
       aes(x = reorder_within(displayName, Accuracy, season),
           y = Accuracy,
           fill = Kicks_made)) +
 geom_col() +
  coord_flip() +
  facet_wrap(~ season, scales = "free_y") +
  scale_x_reordered() +
  scale_y_continuous(
    limits = c(0, 110),
    breaks = seq(0, 100, by = 20),
    labels = scales::label_number(suffix = "%")
  ) +
  scale_fill_gradient2(
    low = "darkred",
    mid = "lightyellow",
    high = "darkgreen",
    midpoint = mean(top10$Kicks_made),
    name = "Kicks Made"
  ) +
  geom_text(
    aes(label = percent(Accuracy*0.01, accuracy = 1)),
    color = "black",
    hjust = -0.2,
    size = 2.0
  ) +
  geom_text(
    aes(label = paste("Kicks made: ",Kicks_made,"of",Attempts), y = 30),
    color = "black",
    hjust = 0.5,
    size = 2.0
  ) +
  labs(
    title = "Top 10 Kickers by Accuracy by Season (Ranked by Annual Accuracy)",
    subtitle = "(Based on kickers with at least the average number of attempts over all years)",
    x = "Kicker",
    y = "Accuracy",
    fill = "Kicks Made"
  ) +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face="bold"),
        plot.subtitle = element_text(
          size = 9,
          face = "plain",
          hjust = 0.5
        ),
        axis.text.x = element_text(size = 8))