### Development setup commands for sdvplotR Source: https://sdvplotr.sportsdataverse.org/CONTRIBUTING.html Install required R packages and run the standard devtools workflow (load_all, test, document, check). Requires R >= 4.1. ```r # R >= 4.1 install.packages(c("devtools", "roxygen2", "testthat", "pkgdown", "styler", "lintr")) devtools::load_all() devtools::test() devtools::document() devtools::check() ``` -------------------------------- ### Install sdvplotR using pak Source: https://sdvplotr.sportsdataverse.org/index.html Recommended installation method for the R package sdvplotR. Installs the pak package if not already available, then installs sdvplotR from GitHub. ```r if (!requireNamespace("pak", quietly = TRUE)) { install.packages("pak") } pak::pak("sportsdataverse/sdvplotR") ``` -------------------------------- ### Setup: Load libraries and get team abbreviations Source: https://sdvplotr.sportsdataverse.org/articles/leaderboard-dashboards.html Loads required packages (sdvplotR, ggplot2, dplyr, gt) and retrieves valid team abbreviations for NFL, NBA, and CFB using sdv_teams(). ```r library(sdvplotR) library(ggplot2) library(dplyr) library(gt) # Get valid team abbreviations nfl_teams <- sdv_teams("nfl")$abbr nba_teams <- sdv_teams("nba")$abbr cfb_teams <- sdv_teams("cfb")$abbr ``` -------------------------------- ### gt_sdv_wordmarks example Source: https://sdvplotr.sportsdataverse.org/reference/gt_sdv_wordmarks.html Creates a gt table with team wordmarks for NFL teams. The example is wrapped in \donttest{} and requires the gt package. ```r # \donttest{ library(gt) df <- data.frame(team = c("KC", "BUF", "SF"), wins = c(14, 13, 12)) df |> gt() |> gt_sdv_wordmarks(columns = "team", league = "nfl") team | wins ---|--- | 14 | 13 | 12 # } ``` -------------------------------- ### Load gt and create subset data for gt_spotlight examples Source: https://sdvplotr.sportsdataverse.org/reference/gt_spotlight.html Loads the gt package and creates a subset of the sdv_example_standings data containing NFC North and NFC West teams with selected columns. This data is used in all subsequent examples. ```r library(gt) nfc <- subset( sdv_example_standings, division %in% c("NFC North", "NFC West"), c(team_name, wins, losses, conference_rank) ) ``` -------------------------------- ### Install development version of sdvplotR from GitHub Source: https://sdvplotr.sportsdataverse.org/index.html Installs the development version of sdvplotR from GitHub. ```r remotes::install_github("sportsdataverse/sdvplotR") ``` -------------------------------- ### Install sdvplotR from R-universe Source: https://sdvplotr.sportsdataverse.org/index.html Alternative installation method for the R package sdvplotR using binary builds from R-universe. ```r install.packages("sdvplotR", repos = c("https://sportsdataverse.r-universe.dev", "https://cloud.r-project.org")) ``` -------------------------------- ### sdv_leagues() example with output Source: https://sdvplotr.sportsdataverse.org/reference/sdv_leagues.html Example call to sdv_leagues() showing the returned sorted character vector of league keys, including 'aaf', 'cfb', 'mlb', 'nfl', 'wnba', and others. ```r sdv_leagues() #> [1] "aaf" "ahl" "cfb" "cricket" #> [5] "echl" "mbb" "milb" "mlb" #> [9] "nba" "nbagl" "ncaa_baseball" "ncaa_mhockey" #> [13] "ncaa_softball" "ncaa_whockey" "nfl" "nhl" #> [17] "ohl" "phf" "pwhl" "qmjhl" #> [21] "soccer" "ufl" "usfl" "ushl" #> [25] "wbb" "whl" "wnba" "xfl" ``` -------------------------------- ### Load libraries and define helpers for season selection Source: https://sdvplotr.sportsdataverse.org/articles/leaderboard-mlb.html Sets up the environment and defines helper functions: `live()` wraps API calls to return NULL on error, `unavailable()` formats a note, and `standings_for()` fetches standings or returns NULL before opening day. It then determines the season, checks availability, and builds a status message using the MLB Stats API calendar. ```r library(sdvplotR) library(dplyr, warn.conflicts = FALSE) library(ggplot2) library(gt) today <- Sys.Date() current <- as.integer(format(today, "%Y")) # the season runs inside one calendar year # A live API call, or NULL when the API does not answer: one bad week then shows # a note in place of a table instead of failing the whole site build live <- function(expr) tryCatch(expr, error = function(e) NULL) unavailable <- function(what, ok) { if (ok) "" else sprintf("*%s were unavailable when this page was built on %s; they return next week.*", what, today) } # A season's standings from the MLB Stats API, or NULL before opening day: the # API answers with no rows for a season it has no standings for, or with every # team on zero games standings_for <- function(season) { table <- live(baseballr::mlb_standings(season = season, league_id = "103,104")) if (NROW(table) == 0 || max(table$team_records_games_played) == 0) NULL else table } season <- current raw_standings <- standings_for(season) if (is.null(raw_standings)) { season <- current - 1 raw_standings <- standings_for(season) } # last season always has standings, so none for either season means the API did not answer available <- !is.null(raw_standings) leaders_ok <- FALSE # The Stats API's calendar for the current season: when its regular season and # postseason end calendar <- live(baseballr::mlb_seasons(sport_id = 1)) regular_end <- as.Date(as.character(calendar$regular_season_end_date[calendar$season_id == current])) post_end <- as.Date(as.character(calendar$post_season_end_date[calendar$season_id == current])) games_per_team <- if (available) round(median(raw_standings$team_records_games_played)) else NA if (!available) { status <- "the MLB Stats API did not answer when this page was built, so this week's tables and chart are missing; they return next week." through <- "" } else if (season < current) { status <- sprintf( "the offseason, so this is the final %d regular season; the %d season has no games yet.", season, current ) through <- "final regular season" } else if (length(regular_end) == 1 && today <= regular_end) { status <- sprintf("the %d season to date, about %d games per team.", season, games_per_team) through <- paste("through", games_per_team, "games") } else if (length(post_end) == 1 && today <= post_end) { status <- sprintf("the final %d regular season; the postseason is under way.", season) through <- "final regular season" } else { status <- sprintf("the offseason, so this is the final %d regular season.", season) through <- "final regular season" } ``` -------------------------------- ### Apply locally installed font with gt_set_font Source: https://sdvplotr.sportsdataverse.org/reference/gt_set_font.html Use gt_set_font with from_google_font = FALSE to apply a font that is already installed on the system. The example uses Helvetica on the nfc_south table. ```r gt(nfc_south) |> gt_set_font("Helvetica", from_google_font = FALSE) ``` -------------------------------- ### Example: geom_sdv_wordmarks with NFL teams Source: https://sdvplotr.sportsdataverse.org/reference/geom_sdv_wordmarks.html Creates a ggplot2 plot with wordmarks for the first eight NFL teams. Uses sdv_teams() to get team abbreviations, sets width to 0.12, and adds labels with nudge_y. The example is wrapped in \donttest{}. ```r # \donttest{ library(sdvplotR) library(ggplot2) team_abbr <- sdv_teams("nfl")$abbr[1:8] df <- data.frame( a = rep(1:4, 2), b = sort(rep(1:2, 4), decreasing = TRUE), teams = team_abbr ) ggplot(df, aes(x = a, y = b)) + geom_sdv_wordmarks(aes(team = teams), league = "nfl", width = 0.12) + geom_label(aes(label = teams), nudge_y = -0.20, alpha = 0.5) + scale_x_continuous(expand = expansion(add = 0.5)) + theme_void() } ``` -------------------------------- ### Load sdvplotR and set up plotting environment Source: https://sdvplotr.sportsdataverse.org/articles/cookbook-colors-themes.html Initial setup for using sdvplotR. Loads the package and required libraries for plotting. ```r library(sdvplotR) library(ggplot2) library(dplyr) ``` -------------------------------- ### Setup: Load libraries and set output directory Source: https://sdvplotr.sportsdataverse.org/articles/workflows.html Loads sdvplotR, ggplot2, dplyr, and gt, and sets a temporary output directory. Companion packages are called with pkg:: as needed. Exports go to the temporary directory; point this at your own folder. ```r library(sdvplotR) library(ggplot2) library(dplyr) library(gt) # Companion packages, called with pkg:: below: # nflfastR / nflreadr (NFL), cfbfastR + cfbseedR (CFB), hoopR (NBA, MBB), # wehoop (WNBA, WBB), baseballr (MLB), fastRhockey (NHL), oddsapiR (odds) # Exports go to a temporary directory; point this at your own folder out_dir <- tempdir() ``` -------------------------------- ### Add image to ggplot title with ggtitle_image() Source: https://sdvplotr.sportsdataverse.org/reference/ggtitle_image.html Loads sdvplotR and ggplot2, filters example standings for NFL, creates a scatter plot, and adds a title image using ggtitle_image() with theme_title_image() for styling. Requires the ggtext package to be installed; the example is wrapped in \donttest{}. ```R # \donttest{ library(sdvplotR) library(ggplot2) nfl <- subset(sdv_example_standings, league == "nfl") p <- ggplot(nfl, aes(x = points_for, y = points_against)) + geom_point() + labs( title = "This Title will be overwritten", subtitle = "Points scored and allowed, 2025 regular season" ) if (requireNamespace("ggtext", quietly = TRUE)) { p + ggtitle_image( title_image = "SEA", title = "Seattle Seahawks Analysis", image_height = 20, image_side = "left", league = "nfl" ) + theme_title_image(size = 20, hjust = 0.5) } # } ``` -------------------------------- ### Setup: Load libraries and set theme Source: https://sdvplotr.sportsdataverse.org/articles/mbb-viz.html Loads sdvplotR, ggplot2, dplyr, tidyr, and gt, then sets season, label, source note, and a common ggplot2 theme for all visualizations. ```r library(sdvplotR) library(ggplot2) library(dplyr) library(tidyr) library(gt) season <- 2026 # the 2025-26 season: hoopR names a season by the year it ends label <- "2025-26" source_note <- "Data: hoopR (ESPN) | Viz: sdvplotR" theme_set( theme_minimal(base_size = 12) + theme( plot.title = element_text(face = "bold"), plot.title.position = "plot", plot.caption = element_text(color = "grey40", size = 8), plot.caption.position = "plot", panel.grid.minor = element_blank() ) ) ``` -------------------------------- ### gt_set_font("Helvetica", from_google_font = FALSE) Source: https://sdvplotr.sportsdataverse.org/reference/gt_set_font.html Sets the font for a gt table to a locally installed font. The example applies Helvetica to the nfc_south table. ```APIDOC ## gt_set_font ### Description Sets the font for a gt table. This example uses a locally installed font (Helvetica) by setting `from_google_font = FALSE`. ### Usage ```r gt(nfc_south) |> gt_set_font("Helvetica", from_google_font = FALSE) ``` ### Arguments - **font** (character) - Required - The name of the font to use. - **from_google_font** (logical) - Optional - Whether the font is from Google Fonts. Default is `TRUE`; set to `FALSE` to use a locally installed font. ### Value A `gt_tbl` object with the font applied. ### Example ```r gt(nfc_south) |> gt_set_font("Helvetica", from_google_font = FALSE) ``` ### Notes - The example uses the `nfc_south` data frame, which contains team statistics. - The resulting table displays columns: team_name, wins, losses, ties, win_pct, points_for, points_against. ``` -------------------------------- ### Create a gt table with dark theme and logos using gt_sdv_logos() and gt_theme_midnight() Source: https://sdvplotr.sportsdataverse.org/articles/cookbook-colors-themes.html Builds a gt table of the top five WNBA teams by scoring margin, using gt_sdv_logos() to add logos and gt_theme_midnight() for the dark theme. The table's background matches the chart's background from the previous example. ```R dark |> arrange(desc(diff), team) |> head(5) |> select(team, pf, pa, diff) |> gt() |> gt_sdv_logos(columns = team, league = "wnba") |> fmt_number(columns = c(pf, pa, diff), decimals = 1) |> cols_label(team = "", pf = "Scored", pa = "Allowed", diff = "Margin") |> tab_header(title = "The WNBA's best margins, 2026") |> gt_theme_midnight() ``` -------------------------------- ### Create a preview grid of gt themes with gt_theme_preview Source: https://sdvplotr.sportsdataverse.org/reference/gt_theme_preview.html Builds a data frame from sdv_example_standings and passes it to gt_theme_preview with three themes. The output is a browsable grid of preview tables, one per theme, captioned with the theme name. ```r nfl <- subset( sdv_example_standings, league == "nfl", c(team_name, wins, losses, win_pct) ) gt_theme_preview( nfl, themes = c("gt_theme_sdv", "gt_theme_kenpom", "gt_theme_athletic") ) ``` -------------------------------- ### Apply gt_theme_drench to a gt table Source: https://sdvplotr.sportsdataverse.org/reference/gt_theme_drench.html Creates a gt table from a subset of the sdv_example_standings data and applies the drench theme. The example includes a conditional block that runs only in interactive sessions with webshot2 and Chrome installed. ```r library(gt) southwest <- subset( sdv_example_standings, division == "Southwest", c(team_name, wins, losses, win_pct:points_against) ) gt(southwest) |> gt_theme_drench() ``` ```r if (FALSE) { # interactive() && rlang::is_installed("webshot2") && isTRUE(file.exists(chromote::find_chrome())) ``` -------------------------------- ### Load libraries and set up season, conference, and output directory Source: https://sdvplotr.sportsdataverse.org/articles/recipe-cfb-conference-table.html Loads sdvplotR, gt, and dplyr, then sets the season to 2025, conference to "Big Ten", and creates a temporary output directory for exports. Use your own folder in practice. ```r library(sdvplotR) library(gt) library(dplyr, warn.conflicts = FALSE) season <- 2025 conference <- "Big Ten" out_dir <- tempfile("sdvplotR-recipe-") # where the exports go; use your own folder dir.create(out_dir) ``` -------------------------------- ### Create bar chart with scale_x_sdv and theme_x_sdv Source: https://sdvplotr.sportsdataverse.org/reference/theme_sdv.html Loads sdvplotR and ggplot2, gets NFL team abbreviations, creates a data frame with random values, and plots a bar chart with custom x-axis scale and theme. The plot is only rendered if ggtext is installed. ```R # \donttest{ library(sdvplotR) library(ggplot2) team_abbr <- sdv_teams("nfl")$abbr[1:8] df <- data.frame( random_value = runif(length(team_abbr), 0, 1), teams = team_abbr ) if (requireNamespace("ggtext", quietly = TRUE)) { ggplot(df, aes(x = teams, y = random_value)) + geom_col(width = 0.5) + scale_x_sdv(league = "nfl") + theme_minimal() + theme_x_sdv() } # } ``` -------------------------------- ### Setup libraries and directories for WBB standings recipe Source: https://sdvplotr.sportsdataverse.org/articles/recipe-wbb-conference-standings.html Loads sdvplotR, gt, and dplyr, sets the season to 2026 (2025-26), conference to SEC, and creates an output directory using tempfile(). ```r library(sdvplotR) library(gt) library(dplyr, warn.conflicts = FALSE) season <- 2026 # the 2025-26 season, named by the year it ends conference <- "SEC" out_dir <- tempfile("sdvplotR-recipe-") # where the exports go; use your own folder dir.create(out_dir) ``` -------------------------------- ### plotly: helper function to create logo images Source: https://sdvplotr.sportsdataverse.org/articles/cookbook-interactive.html Defines a helper function that builds a list of plotly layout images from team names and positions. It uses sdv_logo_url() to get the logo URLs and positions each image in data units. This function is used in the subsequent plotly examples. ```R logo_images <- function(teams, x, y, sport, sizex, sizey = sizex, xref = "x", yref = "y") { urls <- sdv_logo_url(teams, league = sport) lapply(seq_along(urls), function(i) { list( source = urls[i], xref = xref, yref = yref, x = x[i], y = y[i], sizex = sizex, sizey = sizey, xanchor = "center", yanchor = "middle", layer = "above" ) }) } ``` -------------------------------- ### Call sdv_versions() to show data versions Source: https://sdvplotr.sportsdataverse.org/reference/sdv_versions.html Returns a list with package, index_version, index_source, manifest_rows, and manifest_source. The example output shows index_source and manifest_source as 'live'. ```r sdv_versions() ``` ```r sdv_versions() #> $package #> [1] "0.1.0" #> #> $index_version #> [1] "0aeef853ec2b" #> #> $index_source #> [1] "live" #> #> $manifest_rows #> [1] 44462 #> #> $manifest_source #> [1] "live" #> ``` -------------------------------- ### Example: Apply gt_theme_midnight to a gt table Source: https://sdvplotr.sportsdataverse.org/reference/gt_theme_midnight.html Creates a gt table from the NFC West subset of sdv_example_standings and applies the midnight theme. The output is a rendered table with team statistics. ```r library(gt) nfc_west <- subset( sdv_example_standings, division == "NFC West", c(team_name, wins:points_against) ) gt(nfc_west) |> gt_theme_midnight() ``` ```text team_name | wins | losses | ties | win_pct | points_for | points_against ---|---|---|---|---|---|--- Seattle Seahawks | 14 | 3 | 0 | 0.824 | 483 | 292 Los Angeles Rams | 12 | 5 | 0 | 0.706 | 518 | 346 San Francisco 49ers | 12 | 5 | 0 | 0.706 | 437 | 371 Arizona Cardinals | 3 | 14 | 0 | 0.176 | 355 | 488 ``` -------------------------------- ### sdv_teams("nfl") example with output Source: https://sdvplotr.sportsdataverse.org/reference/sdv_teams.html Call sdv_teams with the "nfl" league key to get a data frame of NFL teams. The output shows the first 13 rows of the resulting data frame, including columns for league, team_id, abbr, name, short_name, location, program, conference_id, conference, color_primary, and color_secondary. ```r sdv_teams("nfl") #> league team_id abbr name short_name location program #> 1 nfl 1 ATL Atlanta Falcons Falcons Atlanta pro #> 2 nfl 10 TEN Tennessee Titans Titans Tennessee pro #> 3 nfl 11 IND Indianapolis Colts Colts Indianapolis pro #> 4 nfl 12 KC Kansas City Chiefs Chiefs Kansas City pro #> 5 nfl 13 LV Las Vegas Raiders Raiders Las Vegas pro #> 6 nfl 14 LA Los Angeles Rams Rams Los Angeles pro #> 7 nfl 15 MIA Miami Dolphins Dolphins Miami pro #> 8 nfl 16 MIN Minnesota Vikings Vikings Minnesota pro #> 9 nfl 17 NE New England Patriots Patriots New England pro #> 10 nfl 18 NO New Orleans Saints Saints New Orleans pro #> 11 nfl 19 NYG New York Giants Giants New York pro #> 12 nfl 2 BUF Buffalo Bills Bills Buffalo pro #> 13 nfl 20 NYJ New York Jets Jets New York pro #> 14 nfl 21 PHI Philadelphia Eagles Eagles Philadelphia pro #> 15 nfl 22 ARI Arizona Cardinals Cardinals Arizona pro #> 16 nfl 23 PIT Pittsburgh Steelers Steelers Pittsburgh pro #> 17 nfl 24 LAC Los Angeles Chargers Chargers Los Angeles pro #> 18 nfl 25 SF San Francisco 49ers 49ers San Francisco pro #> 19 nfl 26 SEA Seattle Seahawks Seahawks Seattle pro #> 20 nfl 27 TB Tampa Bay Buccaneers Buccaneers Tampa Bay pro #> 21 nfl 28 WAS Washington Commanders Commanders Washington pro #> 22 nfl 29 CAR Carolina Panthers Panthers Carolina pro #> 23 nfl 3 CHI Chicago Bears Bears Chicago pro #> 24 nfl 30 JAX Jacksonville Jaguars Jaguars Jacksonville pro #> 25 nfl 33 BAL Baltimore Ravens Ravens Baltimore pro #> 26 nfl 34 HOU Houston Texans Texans Houston pro #> 27 nfl 4 CIN Cincinnati Bengals Bengals Cincinnati pro #> 28 nfl 5 CLE Cleveland Browns Browns Cleveland pro #> 29 nfl 6 DAL Dallas Cowboys Cowboys Dallas pro #> 30 nfl 7 DEN Denver Broncos Broncos Denver pro #> 31 nfl 8 DET Detroit Lions Lions Detroit pro #> 32 nfl 9 GB Green Bay Packers Packers Green Bay pro #> conference_id conference color_primary color_secondary #> 1 nfl:nfc National Football Conference #a71930 #000000 #> 2 nfl:afc American Football Conference #4495d2 #d50a0a #> 3 nfl:afc American Football Conference #002c5f #a5acaf #> 4 nfl:afc American Football Conference #e31837 #ffb612 #> 5 nfl:afc American Football Conference #000000 #a5acaf #> 6 nfl:nfc National Football Conference #003594 #ffd100 #> 7 nfl:afc American Football Conference #008e97 #f58220 #> 8 nfl:nfc National Football Conference #4f2683 #ffc62f #> 9 nfl:afc American Football Conference #002244 #c60c30 #> 10 nfl:nfc National Football Conference #d3bc8d #000000 #> 11 nfl:nfc National Football Conference #0b2265 #a71930 #> 12 nfl:afc American Football Conference #00338d #c60c30 #> 13 nfl:afc American Football Conference #003f2d #000000 ``` -------------------------------- ### Map team colors to data rows with sdv_team_colors() Source: https://sdvplotr.sportsdataverse.org/articles/cookbook-colors-themes.html Uses sdv_team_colors() to add primary and secondary color columns to a data frame of NHL team statistics, then plots them with identity scales. The example uses fastRhockey::load_nhl_team_box() and shows the resulting head() output. Note that unresolved teams get NA and white secondary colors may disappear on white backgrounds. ```R nhl_games <- fastRhockey::load_nhl_team_box(season) |> as.data.frame() |> filter(substr(game_id, 5, 6) == "02") # 02 = regular season nhl_teams <- nhl_games |> summarise(gf = mean(goals), ga = mean(goals_against), .by = team_abbrev) |> arrange(desc(gf), team_abbrev) |> mutate( primary = unname(sdv_team_colors("nhl", team_abbrev)), secondary = unname(sdv_team_colors("nhl", team_abbrev, which = "secondary")) ) head(nhl_teams, 5) #> team_abbrev gf ga primary secondary #> 1 COL 3.682927 2.243902 #860038 #005ea3 #> 2 CAR 3.609756 2.719512 #e30426 #000000 #> 3 PIT 3.573171 2.963415 #000000 #fdb71a #> 4 TBL 3.536585 2.609756 #003e7e #ffffff #> 5 BUF 3.512195 2.695122 #00468b #fdb71a ggplot(nhl_teams, aes(x = gf, y = ga)) + geom_point(aes(fill = primary, colour = secondary), shape = 21, size = 6, stroke = 1.5) + ggrepel::geom_text_repel(aes(label = team_abbrev), size = 2.5, point.size = 6, seed = 1) + scale_fill_identity() + scale_colour_identity() + scale_y_reverse() + labs( title = "NHL goals for and against per game, 2025-26", x = "Goals for per game", y = "Goals against per game (reversed)", caption = "Data: fastRhockey::load_nhl_team_box()" ) + theme_minimal() ``` -------------------------------- ### sdv_colorway() usage example Source: https://sdvplotr.sportsdataverse.org/reference/sdv_colorway.html Example usage of sdv_colorway() with a plotly bar chart, applying team colors for the NFL teams KC and BUF. The example is wrapped in a requireNamespace check for plotly. ```R # \donttest{ if (requireNamespace("plotly", quietly = TRUE)) { plotly::plot_ly(type = "bar") |> sdv_colorway("nfl", c("KC", "BUF")) } # } ``` -------------------------------- ### Load required libraries Source: https://sdvplotr.sportsdataverse.org/articles/delay_tables.html Loads the necessary packages for the examples: sdvplotR, gt, gtExtras, and dplyr. ```r library(sdvplotR) library(gt) library(gtExtras) library(dplyr) ``` -------------------------------- ### Install sdvplotR from CRAN Source: https://sdvplotr.sportsdataverse.org/index.html Installs the released version of sdvplotR from CRAN once it is available. ```r install.packages("sdvplotR") ``` -------------------------------- ### Install JavaScript/TypeScript sdvplot packages Source: https://sdvplotr.sportsdataverse.org/index.html Install the npm packages @sportsdataverse/sdvplot, @sportsdataverse/sdvtables, and @sportsdataverse/sporty. ```bash npm install @sportsdataverse/sdvplot @sportsdataverse/sdvtables @sportsdataverse/sporty ``` -------------------------------- ### Load libraries and set up output directory Source: https://sdvplotr.sportsdataverse.org/articles/recipe-mlb-run-differential.html Loads required packages (sdvplotR, ggplot2, dplyr, patchwork) and creates a temporary output directory for exports. Replace the output directory with your own folder. ```r library(sdvplotR) library(ggplot2) library(dplyr, warn.conflicts = FALSE) library(patchwork) season <- 2026 out_dir <- tempfile("sdvplotR-recipe-") # where the exports go; use your own folder dir.create(out_dir) ``` -------------------------------- ### Load libraries, set season, and fetch play-by-play Source: https://sdvplotr.sportsdataverse.org/articles/leaderboard-cfb-weekly.html Sets up the environment, determines the current season (stepping back if data is unavailable), and defines a function to load play-by-play with error handling. Uses cfbfastR::load_cfb_pbp() and handles NULL returns. ```R library(sdvplotR) library(dplyr, warn.conflicts = FALSE) library(ggplot2) library(gt) today <- Sys.Date() # Week 0 is in late August, so before then the calendar points at last season current <- as.integer(format(today, "%Y")) - (format(today, "%m") < "08") # A season's play-by-play, or NULL when it is not published: load_cfb_pbp() errors # for a season past cfbfastR's most recent one, and warns and returns no rows for # one whose file is not up yet play_by_play <- function(season) { pbp <- tryCatch(suppressWarnings(cfbfastR::load_cfb_pbp(season)), error = function(e) NULL) if (NROW(pbp) == 0) NULL else pbp } season <- current pbp <- play_by_play(season) if (is.null(pbp)) { season <- current - 1 pbp <- play_by_play(season) } stopifnot(!is.null(pbp)) # A live API call, or NULL when the API does not answer: one bad week then shows # a note instead of failing the whole site build live <- function(expr) tryCatch(expr, error = function(e) NULL) # CollegeFootballData.com's schedule (a live API: set CFBD_API_KEY, a free key) schedule <- live(cfbfastR::load_cfb_schedules(season)) schedule_ok <- NROW(schedule) > 0 if (schedule_ok) { played <- schedule |> filter(completed) |> arrange(start_date, game_id) week <- max(played$week[played$season_type == "regular"]) left <- filter(schedule, !completed) } else { week <- max(pbp$week) } if (!schedule_ok) { status <- sprintf( "the %d season through week %d. CollegeFootballData.com's schedule was unavailable when this page was built, so records are missing this week; they return next week.", season, week ) through <- paste("through week", week) } else if (any(left$season_type == "regular")) { status <- sprintf("the %d season through week %d.", season, week) through <- paste("through week", week) } else if (nrow(left) > 0) { status <- sprintf("the %d regular season is final; bowls and the playoff are under way.", season) through <- "regular season and finished bowls" } else { status <- sprintf("the offseason, so this is the final %d season, bowls and playoff included.", season) through <- "final" } ```