# install.packages("trelliscopejs")
library(trelliscopejs)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.0 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
# install.packages("nflfastR")
library(nflfastR)
library(nflplotR)
For a data set of your choosing, make a faceted plot using the trelliscopejs package. You may make any type of plot; scatter plot, histogram, etc. but, as mentioned in the discussion below, you must explain why you chose this plot and what you are investigating about the variable you are graphing.
The trelliscope plot must include one cognostic measure of your own. Include a description of what it is and what information this measure gives.
# Load in 2023 nfl play-by-play
season_23_stats <- load_pbp(seasons = 2023)
# group and summarize stats to focus on games where quarterbacks played more than 10 snaps in a game
season_23_qbs <- season_23_stats %>%
filter(season_type == "REG", pass == 1, strtrim(game_id, 4) == "2023") %>%
group_by(game_id, passer, posteam, home_team, away_team, home_score, away_score, week) %>%
summarize(
n_dropbacks = sum(pass, na.rm = TRUE),
tds = sum(pass_touchdown, na.rm = TRUE),
air_yards = sum(air_yards, na.rm = TRUE),
yards = sum(passing_yards, na.rm = TRUE),
completions = sum(complete_pass, na.rm = TRUE),
attempts = sum(pass_attempt, na.rm = TRUE),
ints = sum(interception, na.rm = TRUE),
passing_first_downs = sum(first_down == 1, na.rm = TRUE),
redzone_attempts = sum(if_else(pass_attempt == 1 & yardline_100 >= 80, 1, 0), na.rm = TRUE),
qb_hits = sum(qb_hit, na.rm = TRUE),
sacks = sum(sack, na.rm = TRUE)
) %>%
filter(n_dropbacks > 10) %>%
mutate(Team = cog(val = posteam, default_label = TRUE))
## `summarise()` has grouped output by 'game_id', 'passer', 'posteam',
## 'home_team', 'away_team', 'home_score', 'away_score'. You can override using
## the `.groups` argument.
# plot
season_23_qbs %>%
ggplot(aes(week, air_yards)) +
geom_point(aes(color = posteam), size = 2.5) +
scale_color_nfl(type = "secondary") +
geom_line(aes(color = posteam)) +
labs(x = "Week", y = "Air Yards") +
theme_bw() +
facet_trelliscope(~ passer + Team,
name = "Passings Yards by Week",
desc = "Passings Yards by Week in 2023 NFL Season",
nrow = 1, ncol = 2,
self_contained = TRUE,
path = ".")
## using data from the first layer
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?
Description 2-3 paragraphs.
Describe the data set. Explain the variable you are graphing in your plots and the reason you are investigating with it. Discuss the reason/motivation you chose the variable to facet on, and what insight or trend you are attempting to investigate. Discuss any challenges you had in making the graphs and how you dealt with these challenges. Name at least one cognostic measure (this can include the cognostic you created or be different) the reader could investigate, and explain any insight they might gain from it.
The dataset is from the nflfastR library, utilizing the load play-by-play function. The data is the play-by-play from the 2023 season. The data is filtered by pass plays only and grouped by quarterbacks. Then, the data is summarized into important game stats for quarterbacks such as pass yards, air yards, sack percentage, etc. The graphs represent the air yards by week for each quarterback. Air yards is indicative of how far a quarterback is throwing the ball and how much work their receiver is doing after the catch, known as yards after the catch (YAC). Air yards depends on the opponent and the run-pass ratio of the offense; however, I was curious to see if air yards was much higher earlier in the season or later in the season. I predicted that air yards would be lower later in the season because it is colder out and teams are more inclined to run the ball in the cold; however, indoor stadiums (e.g., Minnesota Vikings) and fair-weathered teams (e.g., Miami Dolphins) can disprove that theory.
The primary challenge I had with making the graph was putting in team logos for points. The nflplotR package has that capability, but after some research and many failed attempts, I found out that the function I was using is not suited well for facet_wrap. I pivoted to changing the points and lines to a team’s color instead to make each plot distinct. I succeeded in that.
One cognostic measure that the reader could investigate is air_yards_variance. My initial thought when investigating the variance of air yards is comparing veterans to rookies/first-year starters. Veterans are expected to be more consistent than younger players; therefore, they should have a lower variance. However, matchups and team structures can impact that. For example, Lamar Jackson is on a run-heavy team. They regularly deploy two-to-three tight end sets to block for their rushers. On average, he is expected to have a lower number of air yards, but if they were playing a team that was selling out to stop the run, the Ravens could flip a switch and let Lamar chuck it. That resulted in a couple “nuclear” weeks for Lamar. He had multiple weeks below 200 air yards and above 400 air yards.
knit the file to an html document
publish this to an RPubs page.
grading: trelliscope plot[25 points], discussion[25 points]
Note: you can add a url directly to the text and it will be active in the html (and word document if you knit to that)
Example: https://www.google.com
If you want to be fancy and make your url active text, you can do this