Nothing
#' **Get ESPN MLB game data (Pbp, Team and Player Box)**
#' @author Saiem Gilani
#' @param game_id Game ID
#' @return A named list of data frames: Plays, Team, Player
#'
#' `espn_mlb_game_all()` bundles three tibbles returned in one call. Each
#' component is identical to the matching standalone function -- see those
#' for the full column documentation:
#'
#' - **Plays** -- play-by-play, identical to [espn_mlb_pbp()].
#' - **Team** -- team box score, identical to [espn_mlb_team_box()].
#' - **Player** -- player box score, identical to [espn_mlb_player_box()].
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @import rvest
#' @export
#' @keywords MLB Game
#' @family ESPN MLB Functions
#' @examples
#' \donttest{
#' try(espn_mlb_game_all(game_id = 401283399))
#' }
#'
espn_mlb_game_all <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
summary_url <- "http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/summary?"
## Inputs
## game_id
full_url <- paste0(
summary_url,
"event=",
game_id
)
pbp <- list(Plays = NULL, Team = NULL, Player = NULL)
resp <- NULL
plays_df <- NULL
team_box_score <- NULL
player_box_score <- NULL
#---- Fetch the summary endpoint (single outer tryCatch) -------------------
tryCatch(
expr = {
res <- .retry_request(full_url)
check_status(res)
resp <- res %>%
.resp_text()
},
error = function(e) .report_api_error(
e,
hint = "Could not fetch game summary for game_id = {game_id}",
args = .args
),
warning = function(w) {},
finally = {}
)
if (is.null(resp)) {
return(pbp)
}
#---- Play-by-Play ------
tryCatch(
expr = {
plays_df <- helper_espn_mlb_pbp(resp)
if (is.null(plays_df)) {
message(sprintf("%s: No play-by-play data for %s available!", Sys.time(), game_id))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no play-by-play data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
#---- Team Box ------
tryCatch(
expr = {
team_box_score <- helper_espn_mlb_team_box(resp)
if (is.null(team_box_score)) {
message(sprintf("%s: No team box score data for %s available!", Sys.time(), game_id))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no team box score data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
#---- Player Box ------
tryCatch(
expr = {
player_box_score <- helper_espn_mlb_player_box(resp)
if (is.null(player_box_score)) {
message(sprintf("%s: No player box score data for %s available!", Sys.time(), game_id))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no player box score data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
pbp <- c(list(plays_df), list(team_box_score), list(player_box_score))
names(pbp) <- c("Plays", "Team", "Player")
return(pbp)
}
#' **Get ESPN MLB PBP data**
#' @author Saiem Gilani
#' @param game_id Game ID
#' @return A play-by-play data frame.
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |id |character |Play / record identifier. |
#' |sequence_number |character |Play sequence number within the game. |
#' |text |character |Text description of the play. |
#' |away_score |integer |Away team run total after the play. |
#' |home_score |integer |Home team run total after the play. |
#' |scoring_play |logical |TRUE if the play scored a run. |
#' |score_value |integer |Runs scored on the play. |
#' |wallclock |character |Wall-clock timestamp of the play (ISO 8601). |
#' |at_bat_id |character |Identifier of the at-bat the play belongs to. |
#' |summary_type |character |Play summary type. |
#' |outs |integer |Outs in the inning after the play. |
#' |type |character |Type. |
#' |bat_order |integer |Spot in the batting order (1-9; NA if not applicable). |
#' |at_bat_pitch_number |integer |Pitch number within the at-bat. |
#' |pitch_velocity |integer |Pitch velocity (mph). |
#' |trajectory |character |Batted-ball trajectory. |
#' |alternative_play |character |Alternative play. |
#' |type_id |integer |Type id. |
#' |type_text |character |Type text. |
#' |type_type |character |Type type. |
#' |type_alternative_text |character |Type alternative text. |
#' |type_abbreviation |character |Type abbreviation. |
#' |period_type |character |Period type ('inning'). |
#' |period_number |integer |Inning number. |
#' |period_display_value |character |Inning display value (e.g. 'Top 1st'). |
#' |team_id |integer |Unique ESPN team identifier. |
#' |pitch_count_balls |integer |Balls in the count when the pitch was thrown. |
#' |pitch_count_strikes |integer |Strikes in the count when the pitch was thrown. |
#' |result_count_balls |integer |Balls in the count after the pitch. |
#' |result_count_strikes |integer |Strikes in the count after the pitch. |
#' |bats_type |character |Bats type. |
#' |bats_abbreviation |character |Bats abbreviation. |
#' |bats_display_value |character |Bats display value. |
#' |pitch_coordinate_x |integer |Pitch location x-coordinate. |
#' |pitch_coordinate_y |integer |Pitch location y-coordinate. |
#' |pitch_type_id |character |Pitch type identifier. |
#' |pitch_type_text |character |Pitch type description (e.g. 'Four-seam FB'). |
#' |pitch_type_abbreviation |character |Pitch type abbreviation. |
#' |hit_coordinate_x |integer |Batted-ball location x-coordinate. |
#' |hit_coordinate_y |integer |Batted-ball location y-coordinate. |
#' |alternative_type_id |character |Alternative type id. |
#' |alternative_type_text |character |Alternative type text. |
#' |alternative_type_abbreviation |character |Alternative type abbreviation. |
#' |alternative_type_alternative_text |character |Alternative type alternative text. |
#' |alternative_type_type |character |Alternative type type. |
#' |on_first_athlete_id |character |Athlete id of the runner on first base. |
#' |on_second_athlete_id |character |Athlete id of the runner on second base. |
#' |play_id |character |Play id. |
#' |athlete_id_1 |integer |Primary participating athlete id (batter). |
#' |athlete_id_2 |integer |Second participating athlete id (pitcher). |
#' |athlete_id_3 |integer |Third participating athlete id (fielder). |
#' |home_team_id |integer |Home team id. |
#' |home_team_mascot |character |Home team mascot. |
#' |home_team_name |character |Home team name. |
#' |home_team_abbrev |character |Home team abbrev. |
#' |home_team_logo |character |Home team logo. |
#' |home_team_logo_dark |character |Home team logo dark. |
#' |home_team_full_name |character |Home team full name. |
#' |home_team_color |character |Home team color. |
#' |home_team_alternate_color |character |Home team alternate color. |
#' |home_team_score |integer |Home team score. |
#' |home_team_winner |logical |Home team winner. |
#' |home_team_record |character |Home team record. |
#' |away_team_id |integer |Away team id. |
#' |away_team_mascot |character |Away team mascot. |
#' |away_team_name |character |Away team name. |
#' |away_team_abbrev |character |Away team abbrev. |
#' |away_team_logo |character |Away team logo. |
#' |away_team_logo_dark |character |Away team logo dark. |
#' |away_team_full_name |character |Away team full name. |
#' |away_team_color |character |Away team color. |
#' |away_team_alternate_color |character |Away team alternate color. |
#' |away_team_score |integer |Away team score. |
#' |away_team_winner |logical |Away team winner. |
#' |away_team_record |character |Away team record. |
#' |game_id |integer |Unique ESPN game/event identifier. |
#' |season |integer |Season (4-digit year). |
#' |season_type |integer |ESPN season type (1=pre, 2=regular, 3=postseason, 4=off-season). |
#' |game_date |Date |Game date (YYYY-MM-DD). |
#' |game_date_time |POSIXct |Game start date/time (US/Eastern). |
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @import rvest
#' @export
#' @keywords MLB PBP
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_pbp(game_id = 401071880))
#' }
#'
espn_mlb_pbp <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
summary_url <-
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/summary?"
## Inputs
## game_id
full_url <- paste0(
summary_url,
"event=",
game_id
)
plays_df <- NULL
#---- Play-by-Play ------
tryCatch(
expr = {
res <- .retry_request(full_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
plays_df <- helper_espn_mlb_pbp(resp)
if (is.null(plays_df)) {
return(message(sprintf("%s: No play-by-play data for %s available!", Sys.time(), game_id)))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no play-by-play data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(plays_df)
}
#' **Get ESPN MLB team box scores**
#' @author Saiem Gilani
#' @param game_id Game ID
#' @return A team boxscore data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |game_id |integer |Unique ESPN game/event identifier. |
#' |season |integer |Season (4-digit year). |
#' |season_type |integer |ESPN season type (1=pre, 2=regular, 3=postseason, 4=off-season). |
#' |game_date |Date |Game date (YYYY-MM-DD). |
#' |game_date_time |POSIXct |Game start date/time (US/Eastern). |
#' |team_id |integer |Unique ESPN team identifier. |
#' |team_uid |character |ESPN universal team identifier (UID). |
#' |team_slug |character |URL-safe team identifier. |
#' |team_location |character |Team city / location. |
#' |team_name |character |Team nickname (e.g. 'Yankees'). |
#' |team_abbreviation |character |Short team abbreviation (e.g. 'NYY'). |
#' |team_display_name |character |Full team display name (e.g. 'New York Yankees'). |
#' |team_short_display_name |character |Short team display name. |
#' |team_color |character |Team primary color (hex, no leading '#'). |
#' |team_alternate_color |character |Team alternate color (hex). |
#' |team_logo |character |Team logo image URL. |
#' |batting_games_played |character |Team batting: batting games played. |
#' |batting_team_games_played |character |Team batting: batting team games played. |
#' |batting_hit_by_pitch |character |Team batting: batting hit by pitch. |
#' |batting_ground_balls |character |Team batting: batting ground balls. |
#' |batting_strikeouts |character |Team batting: batting strikeouts. |
#' |batting_rb_is |character |Team batting: batting rb is. |
#' |batting_sac_hits |character |Team batting: batting sac hits. |
#' |batting_hits |character |Team batting: batting hits. |
#' |batting_stolen_bases |character |Team batting: batting stolen bases. |
#' |batting_walks |character |Team batting: batting walks. |
#' |batting_catcher_interference |character |Team batting: batting catcher interference. |
#' |batting_runs |character |Team batting: batting runs. |
#' |batting_gid_ps |character |Team batting: batting gid ps. |
#' |batting_sac_flies |character |Team batting: batting sac flies. |
#' |batting_at_bats |character |Team batting: batting at bats. |
#' |batting_home_runs |character |Team batting: batting home runs. |
#' |batting_grand_slam_home_runs |character |Team batting: batting grand slam home runs. |
#' |batting_runners_left_on_base |character |Team batting: batting runners left on base. |
#' |batting_triples |character |Team batting: batting triples. |
#' |batting_game_winning_rb_is |character |Team batting: batting game winning rb is. |
#' |batting_intentional_walks |character |Team batting: batting intentional walks. |
#' |batting_doubles |character |Team batting: batting doubles. |
#' |batting_fly_balls |character |Team batting: batting fly balls. |
#' |batting_caught_stealing |character |Team batting: batting caught stealing. |
#' |batting_pitches |character |Team batting: batting pitches. |
#' |batting_games_started |character |Team batting: batting games started. |
#' |batting_pinch_at_bats |character |Team batting: batting pinch at bats. |
#' |batting_pinch_hits |character |Team batting: batting pinch hits. |
#' |batting_player_rating |character |Team batting: batting player rating. |
#' |batting_is_qualified |character |Team batting: batting is qualified. |
#' |batting_is_qualified_steals |character |Team batting: batting is qualified steals. |
#' |batting_total_bases |character |Team batting: batting total bases. |
#' |batting_plate_appearances |character |Team batting: batting plate appearances. |
#' |batting_projected_home_runs |character |Team batting: batting projected home runs. |
#' |batting_extra_base_hits |character |Team batting: batting extra base hits. |
#' |batting_runs_created |character |Team batting: batting runs created. |
#' |batting_avg |character |Team batting: batting average. |
#' |batting_pinch_avg |character |Team batting: batting pinch avg. |
#' |batting_slug_avg |character |Team batting: batting slug avg. |
#' |batting_secondary_avg |character |Team batting: batting secondary avg. |
#' |batting_on_base_pct |character |Team batting: batting on base pct. |
#' |batting_ops |character |Team batting: batting ops. |
#' |batting_ground_to_fly_ratio |character |Team batting: batting ground to fly ratio. |
#' |batting_runs_created_per27outs |character |Team batting: batting runs created per27outs. |
#' |batting_batter_rating |character |Team batting: batting batter rating. |
#' |batting_at_bats_per_home_run |character |Team batting: batting at bats per home run. |
#' |batting_stolen_base_pct |character |Team batting: batting stolen base pct. |
#' |batting_pitches_per_plate_appearance |character |Team batting: batting pitches per plate appearance. |
#' |batting_isolated_power |character |Team batting: batting isolated power. |
#' |batting_walk_to_strikeout_ratio |character |Team batting: batting walk to strikeout ratio. |
#' |batting_walks_per_plate_appearance |character |Team batting: batting walks per plate appearance. |
#' |batting_secondary_avg_minus_ba |character |Team batting: batting secondary avg minus ba. |
#' |batting_runs_produced |character |Team batting: batting runs produced. |
#' |batting_runs_ratio |character |Team batting: batting runs ratio. |
#' ...and 128 further ESPN stat columns (full batting / pitching / fielding stat set).
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @import rvest
#' @export
#' @keywords MLB Team Box
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_team_box(game_id = 401071880))
#' }
#'
espn_mlb_team_box <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
summary_url <-
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/summary?"
## Inputs
## game_id
full_url <- paste0(
summary_url,
"event=",
game_id
)
#---- Team Box ------
team_box_score <- NULL
tryCatch(
expr = {
res <- .retry_request(full_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
team_box_score <- helper_espn_mlb_team_box(resp)
if (is.null(team_box_score)) {
return(message(sprintf("%s: No team box score data for %s available!", Sys.time(), game_id)))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no team box score data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(team_box_score)
}
#' **Get ESPN MLB player box scores**
#' @author Saiem Gilani
#' @param game_id Game ID
#' @return A player boxscore data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |game_id |integer |Unique ESPN game/event identifier. |
#' |season |integer |Season (4-digit year). |
#' |season_type |integer |ESPN season type (1=pre, 2=regular, 3=postseason, 4=off-season). |
#' |game_date |Date |Game date (YYYY-MM-DD). |
#' |game_date_time |POSIXct |Game start date/time (US/Eastern). |
#' |stat_group |character |Statistic side this row reports: 'batting' or 'pitching'. |
#' |team_id |integer |Unique ESPN team identifier. |
#' |team_name |character |Team nickname (e.g. 'Yankees'). |
#' |team_abbreviation |character |Short team abbreviation (e.g. 'NYY'). |
#' |team_display_name |character |Full team display name (e.g. 'New York Yankees'). |
#' |athlete_id |integer |Unique ESPN athlete identifier. |
#' |athlete_display_name |character |Athlete display name (full). |
#' |athlete_short_name |character |Athlete short display name. |
#' |athlete_position_name |character |Athlete fielding position (e.g. 'Shortstop', 'Pitcher'). |
#' |athlete_position_abbreviation |character |Position abbreviation (e.g. 'SS', 'P'). |
#' |starter |logical |TRUE if the player started the game. |
#' |bat_order |integer |Spot in the batting order (1-9; NA if not applicable). |
#' |active |logical |TRUE if the row represents an active record. |
#' |h_ab |character |Hits-for-At-bats line (e.g. '2-4'). |
#' |ab |character |At-bats. |
#' |r |character |Runs scored. |
#' |h |character |Hits. |
#' |rbi |character |Runs batted in. |
#' |hr |character |Home runs. |
#' |bb |character |Bases on balls (walks). |
#' |k |character |Strikeouts. |
#' |number_p |character |Pitches seen / thrown. |
#' |avg |character |Batting average. |
#' |obp |character |On-base percentage. |
#' |slg |character |Slugging percentage. |
#' |ip |character |Innings pitched. |
#' |er |character |Earned runs. |
#' |pc_st |character |Pitch count - strikes (e.g. '95-58'). |
#' |era |character |Earned run average. |
#' |pc |character |Pitch count. |
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @import rvest
#' @export
#' @keywords MLB Player Box
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_player_box(game_id = 401071880))
#' }
#'
espn_mlb_player_box <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
summary_url <-
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/summary?"
## Inputs
## game_id
full_url <- paste0(
summary_url,
"event=",
game_id
)
#---- Player Box ------
player_box_score <- NULL
tryCatch(
expr = {
res <- .retry_request(full_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
player_box_score <- helper_espn_mlb_player_box(resp)
if (is.null(player_box_score)) {
return(message(sprintf("%s: No player box score data for %s available!", Sys.time(), game_id)))
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no player box score data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(player_box_score)
}
#' **Get ESPN MLB game rosters**
#' @author Saiem Gilani
#' @param game_id Game ID
#' @return A game rosters data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |athlete_id |integer |Unique ESPN athlete identifier. |
#' |athlete_uid |character |Athlete uid. |
#' |athlete_guid |character |Athlete guid. |
#' |athlete_type |character |Athlete type. |
#' |sdr |integer |Sdr. |
#' |first_name |character |First name. |
#' |last_name |character |Last name. |
#' |full_name |character |Full name. |
#' |athlete_display_name |character |Athlete display name (full). |
#' |short_name |character |Short display name. |
#' |weight |integer |Weight. |
#' |display_weight |character |Display weight. |
#' |height |integer |Height. |
#' |display_height |character |Display height. |
#' |age |integer |Age. |
#' |date_of_birth |character |Date of birth. |
#' |debut_year |integer |Debut year. |
#' |birth_place_city |character |Birth place city. |
#' |birth_place_state |character |Birth place state. |
#' |birth_place_country |character |Birth place country. |
#' |slug |character |Slug. |
#' |headshot_href |character |Headshot href. |
#' |headshot_alt |character |Headshot alt. |
#' |athlete_jersey_number |character |Athlete jersey number. |
#' |position_id |integer |Position id. |
#' |position_name |character |Position name. |
#' |position_display_name |character |Position display name. |
#' |position_abbreviation |character |Position abbreviation. |
#' |position_leaf |logical |Position leaf. |
#' |positions_ref |character |Positions ref. |
#' |positions_id |character |Positions id. |
#' |positions_name |character |Positions name. |
#' |positions_display_name |character |Positions display name. |
#' |positions_abbreviation |character |Positions abbreviation. |
#' |positions_leaf |logical |Positions leaf. |
#' |positions_parent_ref |character |Positions parent ref. |
#' |positions_statistics_ref |character |Positions statistics ref. |
#' |linked |logical |Linked. |
#' |years |integer |Years. |
#' |debut_year_2 |integer |Debut year 2. |
#' |debut_ref |character |Debut ref. |
#' |debut_ref_1 |character |Debut ref 1. |
#' |active |logical |TRUE if the row represents an active record. |
#' |status_id |integer |Status id. |
#' |status_name |character |Game status (e.g. 'STATUS_FINAL'). |
#' |status_type |character |Status type. |
#' |status_abbreviation |character |Status abbreviation. |
#' |bats_type |character |Bats type. |
#' |bats_abbreviation |character |Bats abbreviation. |
#' |bats_display_value |character |Bats display value. |
#' |throws_type |character |Throws type. |
#' |throws_abbreviation |character |Throws abbreviation. |
#' |throws_display_value |character |Throws display value. |
#' |starter |logical |TRUE if the player started the game. |
#' |valid |logical |Valid. |
#' |display_name |character |Display name. |
#' |bat_order |integer |Spot in the batting order (1-9; NA if not applicable). |
#' |record_number |integer |Record number. |
#' |at_bats |list |At bats. |
#' |positions |list |Positions. |
#' |notes |list |Notes. |
#' |subbed_in_did_sub |logical |Subbed in did sub. |
#' |subbed_out_did_sub |logical |Subbed out did sub. |
#' |team_id |integer |Unique ESPN team identifier. |
#' |team_guid |character |ESPN team GUID. |
#' |team_uid |character |ESPN universal team identifier (UID). |
#' |team_sdr |character |Team sdr. |
#' |team_slug |character |URL-safe team identifier. |
#' |team_location |character |Team city / location. |
#' |team_name |character |Team nickname (e.g. 'Yankees'). |
#' |team_abbreviation |character |Short team abbreviation (e.g. 'NYY'). |
#' |team_display_name |character |Full team display name (e.g. 'New York Yankees'). |
#' |team_short_display_name |character |Short team display name. |
#' |team_color |character |Team primary color (hex, no leading '#'). |
#' |team_alternate_color |character |Team alternate color (hex). |
#' |team_is_active |logical |Team is active. |
#' |is_all_star |logical |Is all star. |
#' |logo_href |character |Logo href. |
#' |logo_dark_href |character |Logo dark href. |
#' |logos_href_2 |character |Logos href 2. |
#' |logos_href_3 |character |Logos href 3. |
#' |logos_href_4 |character |Logos href 4. |
#' |logos_width_4 |integer |Logos width 4. |
#' |logos_height_4 |integer |Logos height 4. |
#' |logos_alt_4 |character |Logos alt 4. |
#' |logos_rel_full_4 |character |Logos rel full 4. |
#' |logos_rel_primary_logo_on_white_color |character |Logos rel primary logo on white color. |
#' |logos_last_updated_4 |character |Logos last updated 4. |
#' |logos_href_5 |character |Logos href 5. |
#' |logos_width_5 |integer |Logos width 5. |
#' |logos_height_5 |integer |Logos height 5. |
#' |logos_alt_5 |character |Logos alt 5. |
#' |logos_rel_full_5 |character |Logos rel full 5. |
#' |logos_rel_primary_logo_on_black_color |character |Logos rel primary logo on black color. |
#' |logos_last_updated_5 |character |Logos last updated 5. |
#' |logos_href_6 |character |Logos href 6. |
#' |logos_width_6 |integer |Logos width 6. |
#' |logos_height_6 |integer |Logos height 6. |
#' |logos_alt_6 |character |Logos alt 6. |
#' |logos_rel_full_6 |character |Logos rel full 6. |
#' |logos_rel_primary_logo_on_primary_color |character |Logos rel primary logo on primary color. |
#' |logos_last_updated_6 |character |Logos last updated 6. |
#' |logos_href_7 |character |Logos href 7. |
#' |logos_width_7 |integer |Logos width 7. |
#' |logos_height_7 |integer |Logos height 7. |
#' |logos_alt_7 |character |Logos alt 7. |
#' |logos_rel_full_7 |character |Logos rel full 7. |
#' |logos_rel_primary_logo_on_secondary_color |character |Logos rel primary logo on secondary color. |
#' |logos_last_updated_7 |character |Logos last updated 7. |
#' |logos_href_8 |character |Logos href 8. |
#' |logos_width_8 |integer |Logos width 8. |
#' |logos_height_8 |integer |Logos height 8. |
#' |logos_alt_8 |character |Logos alt 8. |
#' |logos_rel_full_8 |character |Logos rel full 8. |
#' |logos_rel_primary_logo_black |character |Logos rel primary logo black. |
#' |logos_last_updated_8 |character |Logos last updated 8. |
#' |logos_href_9 |character |Logos href 9. |
#' |logos_width_9 |integer |Logos width 9. |
#' |logos_height_9 |integer |Logos height 9. |
#' |logos_alt_9 |character |Logos alt 9. |
#' |logos_rel_full_9 |character |Logos rel full 9. |
#' |logos_rel_primary_logo_white |character |Logos rel primary logo white. |
#' |logos_last_updated_9 |character |Logos last updated 9. |
#' |logos_href_10 |character |Logos href 10. |
#' |logos_width_10 |integer |Logos width 10. |
#' |logos_height_10 |integer |Logos height 10. |
#' |logos_alt_10 |character |Logos alt 10. |
#' |logos_rel_full_10 |character |Logos rel full 10. |
#' |logos_rel_secondary_logo_on_white_color |character |Logos rel secondary logo on white color. |
#' |logos_last_updated_10 |character |Logos last updated 10. |
#' |logos_href_11 |character |Logos href 11. |
#' |logos_width_11 |integer |Logos width 11. |
#' |logos_height_11 |integer |Logos height 11. |
#' |logos_alt_11 |character |Logos alt 11. |
#' |logos_rel_full_11 |character |Logos rel full 11. |
#' |logos_rel_secondary_logo_on_black_color |character |Logos rel secondary logo on black color. |
#' |logos_last_updated_11 |character |Logos last updated 11. |
#' |logos_href_12 |character |Logos href 12. |
#' |logos_width_12 |integer |Logos width 12. |
#' |logos_height_12 |integer |Logos height 12. |
#' |logos_alt_12 |character |Logos alt 12. |
#' |logos_rel_full_12 |character |Logos rel full 12. |
#' |logos_rel_secondary_logo_on_primary_color |character |Logos rel secondary logo on primary color. |
#' |logos_last_updated_12 |character |Logos last updated 12. |
#' |logos_href_13 |character |Logos href 13. |
#' |logos_width_13 |integer |Logos width 13. |
#' |logos_height_13 |integer |Logos height 13. |
#' |logos_alt_13 |character |Logos alt 13. |
#' |logos_rel_full_13 |character |Logos rel full 13. |
#' |logos_rel_secondary_logo_on_secondary_color |character |Logos rel secondary logo on secondary color. |
#' |logos_last_updated_13 |character |Logos last updated 13. |
#' |logos_href_14 |character |Logos href 14. |
#' |logos_width_14 |integer |Logos width 14. |
#' |logos_height_14 |integer |Logos height 14. |
#' |logos_alt_14 |character |Logos alt 14. |
#' |logos_rel_full_14 |character |Logos rel full 14. |
#' |logos_rel_secondary_logo_black |character |Logos rel secondary logo black. |
#' |logos_last_updated_14 |character |Logos last updated 14. |
#' |logos_href_15 |character |Logos href 15. |
#' |logos_width_15 |integer |Logos width 15. |
#' |logos_height_15 |integer |Logos height 15. |
#' |logos_alt_15 |character |Logos alt 15. |
#' |logos_rel_full_15 |character |Logos rel full 15. |
#' |logos_rel_secondary_logo_white |character |Logos rel secondary logo white. |
#' |logos_last_updated_15 |character |Logos last updated 15. |
#' |game_id |integer |Unique ESPN game/event identifier. |
#' |order |integer |Order. |
#' |home_away |character |Venue label for the team ('home' or 'away'). |
#' |winner |logical |Winner. |
#' |nickname |character |Team nickname. |
#' |draft_display_text |character |Draft display text. |
#' |draft_round |integer |Draft round. |
#' |draft_year |integer |Draft year. |
#' |draft_selection |integer |Draft selection. |
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @import rvest
#' @export
#' @keywords MLB Game Roster
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_game_rosters(game_id = 401283399))
#' }
espn_mlb_game_rosters <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
athlete_roster_df <- .empty_baseballr_data("ESPN MLB Game Roster Information from ESPN.com")
tryCatch(
expr = {
play_base_url <- paste0(
"https://sports.core.api.espn.com/v2/sports/baseball/leagues/mlb/events/",
game_id,
"/competitions/",
game_id,
"/competitors/"
)
game_res <- .retry_request(play_base_url)
# Check the result
check_status(game_res)
game_resp <- game_res %>%
.resp_text()
game_df <- jsonlite::fromJSON(game_resp)[["items"]] %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
dplyr::rename("team_statistics_href" = "statistics.$ref")
colnames(game_df) <- gsub(".\\$ref", "_href", colnames(game_df))
game_df <- game_df %>%
dplyr::rename(
"team_id" = "id",
"team_uid" = "uid"
)
game_df$game_id <- game_id
teams_df <- purrr::map_dfr(game_df$team_href, function(x) {
res <- .retry_request(x)
# Check the result
check_status(res)
team_df <- res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
team_df[["links"]] <- NULL
team_df[["injuries"]] <- NULL
team_df[["record"]] <- NULL
team_df[["athletes"]] <- NULL
team_df[["venue"]] <- NULL
team_df[["groups"]] <- NULL
team_df[["ranks"]] <- NULL
team_df[["statistics"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["links"]] <- NULL
team_df[["notes"]] <- NULL
team_df[["franchise"]] <- NULL
team_df[["againstTheSpreadRecords"]] <- NULL
team_df[["oddsRecords"]] <- NULL
team_df[["college"]] <- NULL
team_df[["transactions"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["depthCharts"]] <- NULL
team_df[["awards"]] <- NULL
team_df[["events"]] <- NULL
team_df <- team_df %>%
purrr::map_if(is.list, as.data.frame) %>%
as.data.frame() %>%
dplyr::select(
-dplyr::any_of(
c(
"logos.width",
"logos.height",
"logos.alt",
"logos.rel..full.",
"logos.rel..default.",
"logos.rel..scoreboard.",
"logos.rel..scoreboard..1",
"logos.rel..scoreboard.2",
"logos.lastUpdated",
"logos.width.1",
"logos.height.1",
"logos.alt.1",
"logos.rel..full..1",
"logos.rel..dark.",
"logos.rel..dark..1",
"logos.lastUpdated.1",
"logos.width.2",
"logos.height.2",
"logos.alt.2",
"logos.rel..full..2",
"logos.rel..scoreboard.",
"logos.lastUpdated.2",
"logos.width.3",
"logos.height.3",
"logos.alt.3",
"logos.rel..full..3",
"logos.lastUpdated.3",
"X.ref",
"X.ref.1",
"X.ref.2"
)
)
) %>%
janitor::clean_names()
colnames(team_df)[1:13] <- paste0("team_", colnames(team_df)[1:13])
team_df <- team_df %>%
dplyr::rename(
"logo_href" = "logos_href",
"logo_dark_href" = "logos_href_1"
) %>%
dplyr::left_join(
game_df %>%
dplyr::select(
"game_id",
"team_id",
"team_uid",
"order",
"homeAway",
"winner",
"roster_href"
),
by = c(
"team_id" = "team_id",
"team_uid" = "team_uid"
)
)
})
## Inputs
## game_id
team_roster_df <- purrr::map_dfr(teams_df$team_id, function(x) {
res <- .retry_request(paste0(play_base_url, x, "/roster"))
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
raw_play_df <- jsonlite::fromJSON(resp)[["entries"]]
raw_play_df <- raw_play_df %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
dplyr::mutate(team_id = x) %>%
dplyr::select(-"period", -"forPlayerId", -"active")
raw_play_df <- raw_play_df %>%
dplyr::left_join(teams_df, by = c("team_id" = "team_id"))
})
colnames(team_roster_df) <- gsub(
".\\$ref",
"_href",
colnames(team_roster_df)
)
athlete_roster_df <- purrr::map_dfr(
team_roster_df$athlete_href,
function(x) {
res <- .retry_request(x)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
raw_play_df <- jsonlite::fromJSON(resp, flatten = TRUE)
raw_play_df[["links"]] <- NULL
raw_play_df[["injuries"]] <- NULL
raw_play_df[["teams"]] <- NULL
raw_play_df[["team"]] <- NULL
raw_play_df[["college"]] <- NULL
raw_play_df[["proAthlete"]] <- NULL
raw_play_df[["statistics"]] <- NULL
raw_play_df[["notes"]] <- NULL
raw_play_df[["eventLog"]] <- NULL
raw_play_df[["$ref"]] <- NULL
raw_play_df[["position"]][["$ref"]] <- NULL
raw_play_df2 <- raw_play_df %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
as.data.frame() %>%
dplyr::mutate(id = as.integer(.data$id)) %>%
dplyr::rename(
"athlete_id" = "id",
"athlete_uid" = "uid",
"athlete_guid" = "guid",
"athlete_type" = "type",
"athlete_display_name" = "displayName",
"athlete_jersey_number" = "jersey"
)
raw_play_df2 <- raw_play_df2 %>%
dplyr::left_join(team_roster_df, by = c("athlete_id" = "playerId"))
}
)
colnames(athlete_roster_df) <- gsub(
".\\$ref",
"_href",
colnames(athlete_roster_df)
)
athlete_roster_df <- athlete_roster_df %>%
janitor::clean_names() %>%
dplyr::select(
-dplyr::any_of(c(
"x_ref",
"x_ref_1",
"contract_ref",
"contract_ref_1",
"contract_ref_2",
"draft_ref",
"draft_ref_1",
"athlete_href",
"position_ref",
"position_href",
"roster_href",
"statistics_href"
))
) %>%
dplyr::mutate_at(
c(
"game_id",
"athlete_id",
"team_id",
"position_id",
"status_id",
"sdr"
),
as.integer
) %>%
make_baseballr_data(
"ESPN MLB Game Roster Information from ESPN.com",
Sys.time()
)
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no game roster data for {game_id} available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(athlete_roster_df)
}
#' **Get ESPN MLB team names and IDs**
#' @author Saiem Gilani
#' @return A teams data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |abbreviation |character |Short abbreviation. |
#' |alternate_color |character |Alternate color (hex). |
#' |color |character |Primary color (hex). |
#' |display_name |character |Display name. |
#' |team_id |integer |Unique ESPN team identifier. |
#' |team |character |Team. |
#' |logo |character |Logo image URL. |
#' |logo_dark |character |Dark-mode logo image URL. |
#' |logos_href_3 |character |Logos href 3. |
#' |logos_href_4 |character |Logos href 4. |
#' |logos_href_5 |character |Logos href 5. |
#' |logos_href_6 |character |Logos href 6. |
#' |logos_href_7 |character |Logos href 7. |
#' |logos_href_8 |character |Logos href 8. |
#' |logos_href_9 |character |Logos href 9. |
#' |logos_href_10 |character |Logos href 10. |
#' |logos_href_11 |character |Logos href 11. |
#' |logos_href_12 |character |Logos href 12. |
#' |logos_href_13 |character |Logos href 13. |
#' |logos_href_14 |character |Logos href 14. |
#' |logos_href_15 |character |Logos href 15. |
#' |logos_href_16 |character |Logos href 16. |
#' |mascot |character |Team mascot. |
#' |nickname |character |Team nickname. |
#' |short_name |character |Short display name. |
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows row_number group_by mutate as_tibble ungroup
#' @importFrom tidyr unnest unnest_wider everything pivot_wider
#' @import rvest
#' @export
#' @keywords MLB Teams
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_teams())
#' }
#'
espn_mlb_teams <- function() {
.args <- .capture_args()
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
teams_url <- "http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/teams?limit=1000"
teams <- .empty_baseballr_data("ESPN MLB Teams Information from ESPN.com")
tryCatch(
expr = {
res <- .retry_request(teams_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
leagues <- jsonlite::fromJSON(resp)[["sports"]][["leagues"]][[1]][[
"teams"
]][[1]][["team"]] %>%
dplyr::group_by(.data$id) %>%
tidyr::unnest_wider("logos", names_sep = "_") %>%
tidyr::unnest_wider("logos_href", names_sep = "_") %>%
dplyr::select(
-"logos_width",
-"logos_height",
-"logos_alt",
-"logos_rel"
) %>%
dplyr::ungroup()
if ("records" %in% colnames(leagues)) {
records <- leagues$record
records <- records %>%
tidyr::unnest_wider("items") %>%
tidyr::unnest_wider("stats", names_sep = "_") %>%
dplyr::mutate(row = dplyr::row_number())
stat <- records %>%
dplyr::group_by(.data$row) %>%
purrr::map_if(is.data.frame, list)
stat <- lapply(stat$stats_1, function(x) {
x %>%
purrr::map_if(is.data.frame, list) %>%
dplyr::as_tibble()
})
s <- lapply(stat, function(x) {
tidyr::pivot_wider(x)
})
s <- tibble::tibble(g = s)
stats <- s %>%
tidyr::unnest_wider("g")
records <- dplyr::bind_cols(records %>% dplyr::select("summary"), stats)
leagues <- leagues %>%
dplyr::select(-"record")
}
leagues <- leagues %>%
dplyr::select(
-"links",
-"isActive",
-"isAllStar",
-"uid",
-"slug"
)
teams <- leagues %>%
dplyr::rename(
"logo" = "logos_href_1",
"logo_dark" = "logos_href_2",
"mascot" = "name",
"team" = "location",
"team_id" = "id",
"short_name" = "shortDisplayName",
"alternate_color" = "alternateColor",
"display_name" = "displayName"
) %>%
janitor::clean_names() %>%
dplyr::mutate(team_id = as.integer(.data$team_id)) %>%
make_baseballr_data("ESPN MLB Teams Information from ESPN.com", Sys.time())
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no teams data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(teams)
}
#' **Get ESPN MLB current team roster**
#'
#' @author Saiem Gilani
#' @param team_id Either numeric or character (YYYY)
#' @return A teams data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |team_id |integer |Unique ESPN team identifier. |
#' |team_uid |character |ESPN universal team identifier (UID). |
#' |team_slug |character |URL-safe team identifier. |
#' |team_location |character |Team city / location. |
#' |team_name |character |Team nickname (e.g. 'Yankees'). |
#' |team_abbreviation |character |Short team abbreviation (e.g. 'NYY'). |
#' |team_display_name |character |Full team display name (e.g. 'New York Yankees'). |
#' |team_short_name |character |Team short name. |
#' |team_color |character |Team primary color (hex, no leading '#'). |
#' |team_alternate_color |character |Team alternate color (hex). |
#' |team_is_active |logical |Team is active. |
#' |franchise..ref |character |Franchise..ref. |
#' |franchise.id |character |Franchise.id. |
#' |franchise.uid |character |Franchise.uid. |
#' |franchise.slug |character |Franchise.slug. |
#' |franchise.location |character |Franchise.location. |
#' |franchise.name |character |Franchise.name. |
#' |franchise.abbreviation |character |Franchise.abbreviation. |
#' |franchise.displayName |character |Franchise.displayName. |
#' |franchise.shortDisplayName |character |Franchise.shortDisplayName. |
#' |franchise.color |character |Franchise.color. |
#' |franchise.isActive |logical |Franchise.isActive. |
#' |franchise.venue..ref |character |Franchise.venue..ref. |
#' |franchise.venue.id |character |Franchise.venue.id. |
#' |franchise.venue.fullName |character |Franchise.venue.fullName. |
#' |franchise.venue.shortName |character |Franchise.venue.shortName. |
#' |franchise.venue.address.city |character |Franchise.venue.address.city. |
#' |franchise.venue.address.state |character |Franchise.venue.address.state. |
#' |franchise.venue.address.zipCode |character |Franchise.venue.address.zipCode. |
#' |franchise.venue.grass |logical |Franchise.venue.grass. |
#' |franchise.venue.indoor |logical |Franchise.venue.indoor. |
#' |franchise.venue.images.href |character |Franchise.venue.images.href. |
#' |franchise.venue.images.width |integer |Franchise.venue.images.width. |
#' |franchise.venue.images.height |integer |Franchise.venue.images.height. |
#' |franchise.venue.images.alt |character |Franchise.venue.images.alt. |
#' |franchise.venue.images.rel |list |Franchise.venue.images.rel. |
#' |franchise..ref.1 |character |Franchise..ref.1. |
#' |franchise..ref.2 |character |Franchise..ref.2. |
#' |standingSummary |character |StandingSummary. |
#' |logo |character |Logo image URL. |
#' |logo_dark |character |Dark-mode logo image URL. |
#' |group_id |integer |Group id. |
#' |parent_group_id |integer |Parent group id. |
#' |group_is_conference |logical |Group is conference. |
#' |conference_id |integer |Conference id. |
#' |athlete_id |integer |Unique ESPN athlete identifier. |
#' |athlete_uid |character |Athlete uid. |
#' |athlete_guid |character |Athlete guid. |
#' |athlete_type |character |Athlete type. |
#' |athlete_first_name |character |Athlete first name. |
#' |athlete_last_name |character |Athlete last name. |
#' |athlete_full_name |character |Athlete full name. |
#' |athlete_display_name |character |Athlete display name (full). |
#' |athlete_short_name |character |Athlete short display name. |
#' |athlete_weight |integer |Athlete weight. |
#' |athlete_display_weight |character |Athlete display weight. |
#' |athlete_height |integer |Athlete height. |
#' |athlete_display_height |character |Athlete display height. |
#' |athlete_age |integer |Athlete age. |
#' |athlete_date_of_birth |character |Athlete date of birth. |
#' |athlete_slug |character |Athlete slug. |
#' |athlete_jersey |character |Athlete jersey. |
#' |athlete_linked |logical |Athlete linked. |
#' |athlete_active |logical |Athlete active. |
#' |athlete_positions |list |Athlete positions. |
#' |athlete_hot_zones |list |Athlete hot zones. |
#' |athlete_debut_year |integer |Athlete debut year. |
#' |athlete_nickname |character |Athlete nickname. |
#' |athlete_middle_name |character |Athlete middle name. |
#' |athlete_citizenship |character |Athlete citizenship. |
#' |athlete_alternate_ids_sdr |character |Athlete alternate ids sdr. |
#' |athlete_birth_place_city |character |Athlete birth place city. |
#' |athlete_birth_place_state |character |Athlete birth place state. |
#' |athlete_birth_place_country |character |Athlete birth place country. |
#' |athlete_position_id |character |Athlete position id. |
#' |athlete_position_name |character |Athlete fielding position (e.g. 'Shortstop', 'Pitcher'). |
#' |athlete_position_display_name |character |Athlete position display name. |
#' |athlete_position_abbreviation |character |Position abbreviation (e.g. 'SS', 'P'). |
#' |athlete_position_leaf |logical |Athlete position leaf. |
#' |athlete_experience_years |integer |Athlete experience years. |
#' |athlete_debut_year_2 |integer |Athlete debut year 2. |
#' |athlete_status_id |character |Athlete status id. |
#' |athlete_status_name |character |Athlete status name. |
#' |athlete_status_type |character |Athlete status type. |
#' |athlete_status_abbreviation |character |Athlete status abbreviation. |
#' |athlete_bats_type |character |Athlete bats type. |
#' |athlete_bats_abbreviation |character |Athlete bats abbreviation. |
#' |athlete_bats_display_value |character |Athlete bats display value. |
#' |athlete_throws_type |character |Athlete throws type. |
#' |athlete_throws_abbreviation |character |Athlete throws abbreviation. |
#' |athlete_throws_display_value |character |Athlete throws display value. |
#' |athlete_headshot_href |character |Athlete headshot href. |
#' |athlete_draft_display_text |character |Athlete draft display text. |
#' |athlete_draft_round |integer |Athlete draft round. |
#' |athlete_draft_year |integer |Athlete draft year. |
#' |athlete_draft_selection |integer |Athlete draft selection. |
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows row_number group_by mutate as_tibble ungroup
#' @importFrom tidyr unnest unnest_wider everything pivot_wider
#' @import rvest
#' @export
#' @keywords MLB Team Roster
#' @family ESPN MLB Functions
#' @examples
#' \donttest{
#' try(espn_mlb_team_current_roster(team_id = 13))
#' }
espn_mlb_team_current_roster <- function(team_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
team_roster_full <- .empty_baseballr_data("ESPN MLB Team Current Roster Information from ESPN.com")
tryCatch(
expr = {
teams_base_url <- sprintf(
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/teams/%s?enable=roster",
team_id
)
res <- .retry_request(teams_base_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
team_roster <- resp %>%
jsonlite::fromJSON() %>%
purrr::pluck("team") %>%
purrr::discard_at(c("links", "nextEvent", "record"))
players <- team_roster %>%
purrr::pluck("athletes") %>%
purrr::discard_at(c("links", "injuries", "teams")) %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
dplyr::as_tibble() %>%
dplyr::select(
-dplyr::any_of(c(
"headshot.width",
"headshot.height",
"headshot.alt",
"headshot.rel",
"teams",
"flag.alt",
"flag.rel",
"flag.width",
"flag.height"
))
)
colnames(players) <- paste0("athlete_", colnames(players))
players <- players %>%
dplyr::mutate(
athlete_id = as.integer(.data$athlete_id),
team_id = as.integer(team_id)
) %>%
janitor::clean_names()
conference_info <- team_roster %>%
purrr::pluck("groups") %>%
dplyr::as_tibble() %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
dplyr::rename(dplyr::any_of(c(
"group_id" = "id",
"group_is_conference" = "isConference",
"parent_group_id" = "parent"
))) %>%
dplyr::mutate(
group_id = as.integer(.data$group_id),
conference_id = .data$group_id,
parent_group_id = as.integer(.data$parent_group_id)
)
team_roster_full <- team_roster %>%
purrr::discard_at(c("groups", "athletes")) %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE) %>%
data.frame() %>%
dplyr::slice(1:2) %>%
dplyr::mutate(
logo = .data$logos.href[1],
logo_dark = .data$logos.href[2]
) %>%
dplyr::slice(1) %>%
dplyr::select(
-dplyr::any_of(c(
"logos.href",
"logos.width",
"logos.height",
"logos.alt",
"logos.rel",
"logos.lastUpdated"
))
) %>%
dplyr::rename(dplyr::any_of(c(
"team_id" = "id",
"team_uid" = "uid",
"team_guid" = "guid",
"team_slug" = "slug",
"team_is_active" = "isActive",
"team_type" = "type",
"team_display_name" = "displayName",
"team_short_name" = "shortDisplayName",
"team_location" = "location",
"team_name" = "name",
"team_nickname" = "nickname",
"team_abbreviation" = "abbreviation",
"team_color" = "color",
"team_alternate_color" = "alternateColor"
))) %>%
dplyr::mutate(team_id = as.integer(.data$team_id)) %>%
dplyr::bind_cols(conference_info) %>%
dplyr::left_join(players, by = c("team_id" = "team_id")) %>%
make_baseballr_data(
"ESPN MLB Team Current Roster Information from ESPN.com",
Sys.time()
)
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no team current roster data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(team_roster_full)
}
#' **Get ESPN MLB schedule for a specific year**
#'
#' @param season Either numeric or character (YYYYMMDD)
#' @return Returns a tibble with scoreboard data
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |matchup |character |Full game matchup name. |
#' |matchup_short |character |Short matchup name. |
#' |season |integer |Season (4-digit year). |
#' |season_type |integer |ESPN season type (1=pre, 2=regular, 3=postseason, 4=off-season). |
#' |season_slug |character |Season slug. |
#' |game_id |integer |Unique ESPN game/event identifier. |
#' |game_uid |character |ESPN game UID. |
#' |game_date |Date |Game date (YYYY-MM-DD). |
#' |attendance |integer |Game attendance. |
#' |play_by_play_available |logical |TRUE if play-by-play is available. |
#' |was_suspended |logical |Was suspended. |
#' |notes |logical |Notes. |
#' |status_name |character |Game status (e.g. 'STATUS_FINAL'). |
#' |broadcast_market |character |Broadcast market ('national'/'home'/'away'). |
#' |broadcast_name |character |Broadcast network name. |
#' |batting_leader_value |numeric |Team batting: batting leader value. |
#' |batting_leader_stat |character |Team batting: batting leader stat. |
#' |batting_leader_name |character |Team batting: batting leader name. |
#' |batting_leader_shortname |character |Team batting: batting leader shortname. |
#' |batting_leader_headshot |character |Team batting: batting leader headshot. |
#' |batting_leader_team_id |character |Team batting: batting leader team id. |
#' |batting_leader_pos |character |Team batting: batting leader pos. |
#' |home_run_leader_value |logical |Home run leader value. |
#' |home_run_leader_stat |logical |Home run leader stat. |
#' |home_run_leader_name |logical |Home run leader name. |
#' |home_run_leader_shortname |logical |Home run leader shortname. |
#' |home_run_leader_headshot |logical |Home run leader headshot. |
#' |home_run_leader_team_id |logical |Home run leader team id. |
#' |home_run_leader_pos |logical |Home run leader pos. |
#' |rbi_leader_value |logical |Rbi leader value. |
#' |rbi_leader_stat |logical |Rbi leader stat. |
#' |rbi_leader_name |logical |Rbi leader name. |
#' |rbi_leader_shortname |logical |Rbi leader shortname. |
#' |rbi_leader_headshot |logical |Rbi leader headshot. |
#' |rbi_leader_team_id |logical |Rbi leader team id. |
#' |rbi_leader_pos |logical |Rbi leader pos. |
#' |start_date |character |Start date. |
#' |broadcast |character |Broadcast network. |
#' |highlights |logical |Highlights. |
#' |game_date_time |POSIXct |Game start date/time (US/Eastern). |
#' |home_team_name |character |Home team name. |
#' |home_team_logo |character |Home team logo. |
#' |home_team_abb |character |Home team abb. |
#' |home_team_id |integer |Home team id. |
#' |home_team_location |character |Home team location. |
#' |home_team_full_name |character |Home team full name. |
#' |home_team_color |character |Home team color. |
#' |home_score |integer |Home team run total after the play. |
#' |home_win |integer |Home win. |
#' |home_record |character |Home record. |
#' |away_team_name |character |Away team name. |
#' |away_team_logo |character |Away team logo. |
#' |away_team_abb |character |Away team abb. |
#' |away_team_id |integer |Away team id. |
#' |away_team_location |character |Away team location. |
#' |away_team_full_name |character |Away team full name. |
#' |away_team_color |character |Away team color. |
#' |away_score |integer |Away team run total after the play. |
#' |away_win |integer |Away win. |
#' |away_record |character |Away record. |
#'
#' @import utils
#' @importFrom dplyr select rename any_of mutate
#' @importFrom jsonlite fromJSON
#' @importFrom tidyr unnest_wider unchop hoist
#' @importFrom lubridate with_tz ymd_hm
#' @import rvest
#' @export
#' @family ESPN MLB Functions
#' @examples
#'
#' # Get schedule from date 2022-11-17 (returns 1000 results, max allowable.)
#' \donttest{
#' try(espn_mlb_scoreboard(season = 20230423))
#' }
espn_mlb_scoreboard <- function(season) {
.args <- mget(setdiff(names(formals()), "..."))
max_year <- substr(Sys.Date(), 1, 4)
if (!(as.integer(substr(season, 1, 4)) > 2001)) {
message(paste("Error: Season must be between 2001 and", max_year + 1))
}
# year > 2000
season <- as.character(season)
season_dates <- season
schedule_api <- sprintf(
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard?limit=1000&dates=%s",
season_dates
)
tryCatch(
expr = {
res <- .retry_request(schedule_api)
# Check the result
check_status(res)
raw_sched <- res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
mlb_data <- raw_sched[["events"]] %>%
tibble::tibble(data = .data$.) %>%
tidyr::unnest_wider("data") %>%
tidyr::unchop("competitions") %>%
dplyr::select(
-"id",
-"uid",
-"date",
-"status"
) %>%
tidyr::unnest_wider("competitions") %>%
dplyr::rename(
"matchup" = "name",
"matchup_short" = "shortName",
"game_id" = "id",
"game_uid" = "uid",
"game_date" = "date"
) %>%
tidyr::hoist("status", status_name = list("type", "name")) %>%
dplyr::select(
!dplyr::any_of(
c(
"timeValid",
"neutralSite",
"conferenceCompetition",
"recent",
"venue",
"type"
)
)
) %>%
tidyr::unnest_wider("season", names_sep = "_") %>%
dplyr::rename("season" = "season_year") %>%
dplyr::select(-dplyr::any_of("status"))
mlb_data <- mlb_data %>%
dplyr::mutate(
game_date_time = lubridate::ymd_hm(substr(
.data$game_date,
1,
nchar(.data$game_date) - 1
)) %>%
lubridate::with_tz(tzone = "America/New_York"),
game_date = as.Date(substr(.data$game_date_time, 1, 10))
)
mlb_data <- mlb_data %>%
tidyr::hoist(
"competitors",
homeAway = list(1, "homeAway")
)
mlb_data <- mlb_data %>%
tidyr::hoist(
"competitors",
team1_team_name = list(1, "team", "name"),
team1_team_logo = list(1, "team", "logo"),
team1_team_abb = list(1, "team", "abbreviation"),
team1_team_id = list(1, "team", "id"),
team1_team_location = list(1, "team", "location"),
team1_team_full = list(1, "team", "displayName"),
team1_team_color = list(1, "team", "color"),
team1_score = list(1, "score"),
team1_win = list(1, "winner"),
team1_record = list(1, "records", 1, "summary"),
# away team
team2_team_name = list(2, "team", "name"),
team2_team_logo = list(2, "team", "logo"),
team2_team_abb = list(2, "team", "abbreviation"),
team2_team_id = list(2, "team", "id"),
team2_team_location = list(2, "team", "location"),
team2_team_full = list(2, "team", "displayName"),
team2_team_color = list(2, "team", "color"),
team2_score = list(2, "score"),
team2_win = list(2, "winner"),
team2_record = list(2, "records", 1, "summary")
)
mlb_data <- mlb_data %>%
dplyr::mutate(
home_team_name = ifelse(
.data$homeAway == "home",
.data$team1_team_name,
.data$team2_team_name
),
home_team_logo = ifelse(
.data$homeAway == "home",
.data$team1_team_logo,
.data$team2_team_logo
),
home_team_abb = ifelse(
.data$homeAway == "home",
.data$team1_team_abb,
.data$team2_team_abb
),
home_team_id = ifelse(
.data$homeAway == "home",
.data$team1_team_id,
.data$team2_team_id
),
home_team_location = ifelse(
.data$homeAway == "home",
.data$team1_team_location,
.data$team2_team_location
),
home_team_full_name = ifelse(
.data$homeAway == "home",
.data$team1_team_full,
.data$team2_team_full
),
home_team_color = ifelse(
.data$homeAway == "home",
.data$team1_team_color,
.data$team2_team_color
),
home_score = ifelse(
.data$homeAway == "home",
.data$team1_score,
.data$team2_score
),
home_win = ifelse(
.data$homeAway == "home",
.data$team1_win,
.data$team2_win
),
home_record = ifelse(
.data$homeAway == "home",
.data$team1_record,
.data$team2_record
),
away_team_name = ifelse(
.data$homeAway == "away",
.data$team1_team_name,
.data$team2_team_name
),
away_team_logo = ifelse(
.data$homeAway == "away",
.data$team1_team_logo,
.data$team2_team_logo
),
away_team_abb = ifelse(
.data$homeAway == "away",
.data$team1_team_abb,
.data$team2_team_abb
),
away_team_id = ifelse(
.data$homeAway == "away",
.data$team1_team_id,
.data$team2_team_id
),
away_team_location = ifelse(
.data$homeAway == "away",
.data$team1_team_location,
.data$team2_team_location
),
away_team_full_name = ifelse(
.data$homeAway == "away",
.data$team1_team_full,
.data$team2_team_full
),
away_team_color = ifelse(
.data$homeAway == "away",
.data$team1_team_color,
.data$team2_team_color
),
away_score = ifelse(
.data$homeAway == "away",
.data$team1_score,
.data$team2_score
),
away_win = ifelse(
.data$homeAway == "away",
.data$team1_win,
.data$team2_win
),
away_record = ifelse(
.data$homeAway == "away",
.data$team1_record,
.data$team2_record
)
)
mlb_data <- mlb_data %>%
dplyr::mutate_at(
c(
"game_id",
"home_team_id",
"home_win",
"away_team_id",
"away_win",
"home_score",
"away_score"
),
as.integer
)
mlb_data <- mlb_data %>%
dplyr::select(
-dplyr::any_of(dplyr::starts_with("team1")),
-dplyr::any_of(dplyr::starts_with("team2")),
-dplyr::any_of(c("homeAway"))
)
if ("leaders" %in% names(mlb_data)) {
schedule_out <- mlb_data %>%
tidyr::hoist(
"leaders",
# batting-average leader (category 1)
batting_leader_value = list(1, "leaders", 1, "value"),
batting_leader_stat = list(1, "leaders", 1, "displayValue"),
batting_leader_name = list(
1,
"leaders",
1,
"athlete",
"displayName"
),
batting_leader_shortname = list(
1,
"leaders",
1,
"athlete",
"shortName"
),
batting_leader_headshot = list(
1,
"leaders",
1,
"athlete",
"headshot"
),
batting_leader_team_id = list(1, "leaders", 1, "team", "id"),
batting_leader_pos = list(
1,
"leaders",
1,
"athlete",
"position",
"abbreviation"
),
# home-runs leader (category 2)
home_run_leader_value = list(2, "leaders", 1, "value"),
home_run_leader_stat = list(2, "leaders", 1, "displayValue"),
home_run_leader_name = list(
2,
"leaders",
1,
"athlete",
"displayName"
),
home_run_leader_shortname = list(
2,
"leaders",
1,
"athlete",
"shortName"
),
home_run_leader_headshot = list(
2,
"leaders",
1,
"athlete",
"headshot"
),
home_run_leader_team_id = list(2, "leaders", 1, "team", "id"),
home_run_leader_pos = list(
2,
"leaders",
1,
"athlete",
"position",
"abbreviation"
),
# RBIs leader (category 3)
rbi_leader_value = list(3, "leaders", 1, "value"),
rbi_leader_stat = list(3, "leaders", 1, "displayValue"),
rbi_leader_name = list(
3,
"leaders",
1,
"athlete",
"displayName"
),
rbi_leader_shortname = list(
3,
"leaders",
1,
"athlete",
"shortName"
),
rbi_leader_headshot = list(
3,
"leaders",
1,
"athlete",
"headshot"
),
rbi_leader_team_id = list(3, "leaders", 1, "team", "id"),
rbi_leader_pos = list(
3,
"leaders",
1,
"athlete",
"position",
"abbreviation"
),
)
if (
"broadcasts" %in%
names(schedule_out) &&
!any(is.na(schedule_out[["broadcasts"]]))
) {
schedule_out %>%
tidyr::hoist(
"broadcasts",
broadcast_market = list(1, "market"),
broadcast_name = list(1, "names", 1)
) %>%
dplyr::select(!where(is.list)) %>%
janitor::clean_names() %>%
make_baseballr_data(
"ESPN MLB Scoreboard Information from ESPN.com",
Sys.time()
)
} else {
schedule_out %>%
janitor::clean_names() %>%
make_baseballr_data(
"ESPN MLB Scoreboard Information from ESPN.com",
Sys.time()
)
}
} else {
if (
"broadcasts" %in%
names(mlb_data) &&
!any(is.na(mlb_data[["broadcasts"]]))
) {
mlb_data %>%
tidyr::hoist(
"broadcasts",
broadcast_market = list(1, "market"),
broadcast_name = list(1, "names", 1)
) %>%
dplyr::select(!where(is.list)) %>%
janitor::clean_names() %>%
make_baseballr_data(
"ESPN MLB Scoreboard Information from ESPN.com",
Sys.time()
)
} else {
mlb_data %>%
dplyr::select(!where(is.list)) %>%
janitor::clean_names() %>%
make_baseballr_data(
"ESPN MLB Scoreboard Information from ESPN.com",
Sys.time()
)
}
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no scoreboard data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
}
#' **Get ESPN MLB's Standings**
#'
#' @param year Either numeric or character (YYYY)
#' @return A standings data frame
#'
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |team_id |integer |Unique ESPN team identifier. |
#' |team |character |Team. |
#' |otlosses |character |Otlosses. |
#' |otwins |character |Otwins. |
#' |avgpointsagainst |numeric |Avgpointsagainst. |
#' |avgpointsfor |numeric |Avgpointsfor. |
#' |clincher |numeric |Clincher. |
#' |differential |numeric |Differential. |
#' |divisionwinpercent |numeric |Divisionwinpercent. |
#' |gamesbehind |numeric |Gamesbehind. |
#' |gamesplayed |character |Gamesplayed. |
#' |leaguewinpercent |numeric |Leaguewinpercent. |
#' |losses |numeric |Losses. |
#' |playoffseed |numeric |Playoffseed. |
#' |pointdifferential |character |Pointdifferential. |
#' |points |character |Points. |
#' |pointsagainst |character |Pointsagainst. |
#' |pointsfor |character |Pointsfor. |
#' |streak |numeric |Streak. |
#' |ties |character |Ties. |
#' |winpercent |numeric |Winpercent. |
#' |wins |numeric |Wins. |
#' |divisiongamesbehind |character |Divisiongamesbehind. |
#' |divisionpercent |character |Divisionpercent. |
#' |divisiontied |character |Divisiontied. |
#' |homelosses |character |Homelosses. |
#' |hometies |character |Hometies. |
#' |homewins |character |Homewins. |
#' |magicnumberdivision |character |Magicnumberdivision. |
#' |magicnumberwildcard |character |Magicnumberwildcard. |
#' |playoffpercent |character |Playoffpercent. |
#' |roadlosses |character |Roadlosses. |
#' |roadties |character |Roadties. |
#' |roadwins |character |Roadwins. |
#' |wildcardpercent |character |Wildcardpercent. |
#' |total |character |Total. |
#' |home |character |Home. |
#' |road |character |Road. |
#' |intradivision |character |Intradivision. |
#' |intraleague |character |Intraleague. |
#' |lasttengames |character |Lasttengames. |
#'
#' @importFrom rlang .data
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr select rename
#' @importFrom tidyr pivot_wider
#' @importFrom data.table rbindlist
#' @export
#' @keywords MLB Standings
#' @family ESPN MLB Functions
#' @examples
#' \donttest{
#' try(espn_mlb_standings(year = 2021))
#' }
espn_mlb_standings <- function(year) {
.args <- mget(setdiff(names(formals()), "..."))
standings_url <- "https://site.web.api.espn.com/apis/v2/sports/baseball/mlb/standings?region=us&lang=en&contentorigin=espn&type=0&level=1&sort=winpercent%3Adesc%2Cwins%3Adesc%2Cgamesbehind%3Aasc&"
## Inputs
## year
full_url <- paste0(
standings_url,
"season=",
year
)
standings <- .empty_baseballr_data("ESPN MLB Standings Information from ESPN.com")
tryCatch(
expr = {
res <- .retry_request(full_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
raw_standings <- jsonlite::fromJSON(resp)[["standings"]]
# Create a dataframe of all MLB teams by extracting from the raw_standings file
teams <- raw_standings[["entries"]][["team"]]
teams <- teams %>%
dplyr::select("id", "displayName") %>%
dplyr::rename(
"team_id" = "id",
"team" = "displayName"
)
# creating a dataframe of the MLB raw standings table from ESPN
standings_df <- raw_standings[["entries"]][["stats"]]
standings_data <- data.table::rbindlist(
standings_df,
fill = TRUE,
idcol = T
)
# Use the following code to replace NA's in the dataframe with the correct corresponding values and removing all unnecessary columns
standings_data$value <- ifelse(
is.na(standings_data$value) & !is.na(standings_data$summary),
standings_data$summary,
standings_data$value
)
standings_data <- standings_data %>%
dplyr::select(
".id",
"type",
"value"
)
# Use pivot_wider to transpose the dataframe so that we now have a standings row for each team
standings_data <- standings_data %>%
tidyr::pivot_wider(names_from = "type", values_from = "value")
standings_data <- standings_data %>%
dplyr::select(-".id")
# joining the 2 dataframes together to create a standings table
standings <- cbind(teams, standings_data) %>%
dplyr::mutate(team_id = as.integer(.data$team_id)) %>%
dplyr::mutate_at(
c(
"avgpointsagainst",
"avgpointsfor",
"clincher",
"differential",
"divisionwinpercent",
"gamesbehind",
"leaguewinpercent",
"losses",
"playoffseed",
"streak",
"winpercent",
"wins"
),
as.numeric
)
standings <- standings %>%
make_baseballr_data(
"ESPN MLB Standings Information from ESPN.com",
Sys.time()
)
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no standings data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(standings)
}
#' **Get ESPN MLB's Betting information**
#'
#' @param game_id Game ID
#' @returns Returns a named list of data frames: pickcenter, againstTheSpread, predictor
#'
#' **pickcenter**
#'
#'
#' |col_name |types |description |
#' |:------------------------------------|:---------|:--------------------------------------------|
#' |details |character |Details. |
#' |over_under |numeric |Over under. |
#' |spread |numeric |Spread. |
#' |provider_id |integer |Unique identifier for provider. |
#' |provider_name |character |Provider name. |
#' |provider_priority |integer |Provider priority. |
#' |away_team_odds_favorite |logical |Away team's team odds favorite. |
#' |away_team_odds_underdog |logical |Away team's team odds underdog. |
#' |away_team_odds_money_line |integer |Away team's team odds money line. |
#' |away_team_odds_spread_odds |numeric |Away team's team odds spread odds. |
#' |away_team_odds_team_id |integer |Unique identifier for away team odds team. |
#' |away_team_odds_win_percentage |numeric |Away team odds win percentage (0-1 decimal). |
#' |away_team_odds_average_score |numeric |Away team's team odds average score. |
#' |away_team_odds_money_line_odds |numeric |Away team's team odds money line odds. |
#' |away_team_odds_spread_return |numeric |Away team's team odds spread return. |
#' |away_team_odds_spread_record_wins |integer |Away team's team odds spread record wins. |
#' |away_team_odds_spread_record_losses |integer |Away team's team odds spread record losses. |
#' |away_team_odds_spread_record_pushes |integer |Away team's team odds spread record pushes. |
#' |away_team_odds_spread_record_summary |character |Away team's team odds spread record summary. |
#' |home_team_odds_favorite |logical |Home team's team odds favorite. |
#' |home_team_odds_underdog |logical |Home team's team odds underdog. |
#' |home_team_odds_money_line |integer |Home team's team odds money line. |
#' |home_team_odds_spread_odds |numeric |Home team's team odds spread odds. |
#' |home_team_odds_team_id |integer |Unique identifier for home team odds team. |
#' |home_team_odds_win_percentage |numeric |Home team odds win percentage (0-1 decimal). |
#' |home_team_odds_average_score |numeric |Home team's team odds average score. |
#' |home_team_odds_money_line_odds |numeric |Home team's team odds money line odds. |
#' |home_team_odds_spread_return |numeric |Home team's team odds spread return. |
#' |home_team_odds_spread_record_wins |integer |Home team's team odds spread record wins. |
#' |home_team_odds_spread_record_losses |integer |Home team's team odds spread record losses. |
#' |home_team_odds_spread_record_pushes |integer |Home team's team odds spread record pushes. |
#' |home_team_odds_spread_record_summary |character |Home team's team odds spread record summary. |
#' |game_id |integer |Unique game identifier. |
#'
#' **againstTheSpread**
#'
#'
#' |col_name |types |description |
#' |:------------|:---------|:---------------------------------------|
#' |id |integer |Id. |
#' |uid |character |ESPN UID string (universal identifier). |
#' |display_name |character |Display name. |
#' |abbreviation |character |Short abbreviation. |
#' |logo |character |Team or league logo URL. |
#' |logos |list |Logos. |
#' |records |list |Records. |
#' |game_id |integer |Unique game identifier. |
#' |team_id |integer |Unique team identifier. |
#'
#' **predictor**
#'
#'
#' |col_name |types |description |
#' |:-------------------------|:-------|:------------------------------------|
#' |game_id |integer |Unique game identifier. |
#' |home_team_id |integer |Unique identifier for the home team. |
#' |away_team_id |integer |Unique identifier for the away team. |
#' |away_team_game_projection |numeric |Away team's team game projection. |
#' |away_team_chance_loss |numeric |Away team's team chance loss. |
#'
#' @importFrom rlang .data
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr select rename
#' @export
#' @keywords MLB Betting
#' @family ESPN MLB Functions
#' @examples
#' \donttest{
#' try(espn_mlb_betting(game_id = 401283399))
#' }
espn_mlb_betting <- function(game_id) {
.args <- mget(setdiff(names(formals()), "..."))
old <- options(list(stringsAsFactors = FALSE, scipen = 999))
on.exit(options(old))
summary_url <-
"http://site.api.espn.com/apis/site/v2/sports/baseball/mlb/summary?"
## Inputs
## game_id
full_url <- paste0(
summary_url,
"event=",
game_id
)
pickcenter <- data.frame()
againstTheSpread <- data.frame()
predictor_df <- data.frame()
betting <- NULL
tryCatch(
expr = {
res <- .retry_request(full_url)
# Check the result
check_status(res)
resp <- res %>%
.resp_text()
raw_summary <- jsonlite::fromJSON(resp)
if ("pickcenter" %in% names(raw_summary)) {
pickcenter <- jsonlite::fromJSON(
jsonlite::toJSON(raw_summary$pickcenter),
flatten = TRUE
) %>%
janitor::clean_names() %>%
dplyr::select(-dplyr::any_of("links")) %>%
dplyr::mutate(game_id = as.integer(game_id)) %>%
dplyr::mutate(dplyr::across(dplyr::any_of(c(
"provider_id",
"away_team_odds_team_id",
"home_team_odds_team_id"
)), as.integer)) %>%
make_baseballr_data(
"ESPN MLB Pickcenter Information from ESPN.com",
Sys.time()
)
}
if ("againstTheSpread" %in% names(raw_summary)) {
againstTheSpread <- jsonlite::fromJSON(jsonlite::toJSON(
raw_summary$againstTheSpread
)) %>%
janitor::clean_names()
teams <- againstTheSpread$team %>%
dplyr::select(-dplyr::any_of("links")) %>%
janitor::clean_names()
records <- againstTheSpread$records
teams$records <- records
againstTheSpread <- teams %>%
dplyr::mutate(
game_id = as.integer(game_id),
id = as.integer(.data$id),
team_id = as.integer(.data$id)
) %>%
make_baseballr_data(
"ESPN MLB Against the Spread Information from ESPN.com",
Sys.time()
)
}
if ("predictor" %in% names(raw_summary)) {
predictor_df <- data.frame(
game_id = as.integer(game_id),
home_team_id = as.integer(raw_summary$predictor$homeTeam$id),
away_team_id = as.integer(raw_summary$predictor$awayTeam$id),
away_team_game_projection = as.numeric(
raw_summary$predictor$awayTeam$gameProjection
),
away_team_chance_loss = as.numeric(
raw_summary$predictor$awayTeam$teamChanceLoss
)
)
predictor_df <- predictor_df %>%
make_baseballr_data(
"ESPN MLB Predictor Information from ESPN.com",
Sys.time()
)
}
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no betting data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
betting <- c(list(pickcenter), list(againstTheSpread), list(predictor_df))
names(betting) <- c("pickcenter", "againstTheSpread", "predictor")
return(betting)
}
#' @title
#' **Get ESPN MLB team stats data**
#' @author Saiem Gilani
#' @param team_id Team ID
#' @param year Year
#' @param season_type (character, default: regular): Season type - regular or postseason
#' @param total (boolean, default: FALSE): Totals
#' @return Returns a tibble with the team stats data
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |team_id |integer |Unique ESPN team identifier. |
#' |team_guid |character |ESPN team GUID. |
#' |team_uid |character |ESPN universal team identifier (UID). |
#' |team_sdr |character |Team sdr. |
#' |team_slug |character |URL-safe team identifier. |
#' |team_location |character |Team city / location. |
#' |team_name |character |Team nickname (e.g. 'Yankees'). |
#' |team_abbreviation |character |Short team abbreviation (e.g. 'NYY'). |
#' |team_display_name |character |Full team display name (e.g. 'New York Yankees'). |
#' |team_short_display_name |character |Short team display name. |
#' |team_color |character |Team primary color (hex, no leading '#'). |
#' |team_alternate_color |character |Team alternate color (hex). |
#' |team_is_active |logical |Team is active. |
#' |is_all_star |logical |Is all star. |
#' |logo_href |character |Logo href. |
#' |logo_dark_href |character |Logo dark href. |
#' |logos_href_2 |character |Logos href 2. |
#' |logos_href_3 |character |Logos href 3. |
#' |logos_href_4 |character |Logos href 4. |
#' |logos_width_4 |integer |Logos width 4. |
#' |logos_height_4 |integer |Logos height 4. |
#' |logos_alt_4 |character |Logos alt 4. |
#' |logos_rel_full_4 |character |Logos rel full 4. |
#' |logos_rel_primary_logo_on_white_color |character |Logos rel primary logo on white color. |
#' |logos_last_updated_4 |character |Logos last updated 4. |
#' |logos_href_5 |character |Logos href 5. |
#' |logos_width_5 |integer |Logos width 5. |
#' |logos_height_5 |integer |Logos height 5. |
#' |logos_alt_5 |character |Logos alt 5. |
#' |logos_rel_full_5 |character |Logos rel full 5. |
#' |logos_rel_primary_logo_on_black_color |character |Logos rel primary logo on black color. |
#' |logos_last_updated_5 |character |Logos last updated 5. |
#' |logos_href_6 |character |Logos href 6. |
#' |logos_width_6 |integer |Logos width 6. |
#' |logos_height_6 |integer |Logos height 6. |
#' |logos_alt_6 |character |Logos alt 6. |
#' |logos_rel_full_6 |character |Logos rel full 6. |
#' |logos_rel_primary_logo_on_primary_color |character |Logos rel primary logo on primary color. |
#' |logos_last_updated_6 |character |Logos last updated 6. |
#' |logos_href_7 |character |Logos href 7. |
#' |logos_width_7 |integer |Logos width 7. |
#' |logos_height_7 |integer |Logos height 7. |
#' |logos_alt_7 |character |Logos alt 7. |
#' |logos_rel_full_7 |character |Logos rel full 7. |
#' |logos_rel_primary_logo_on_secondary_color |character |Logos rel primary logo on secondary color. |
#' |logos_last_updated_7 |character |Logos last updated 7. |
#' |logos_href_8 |character |Logos href 8. |
#' |logos_width_8 |integer |Logos width 8. |
#' |logos_height_8 |integer |Logos height 8. |
#' |logos_alt_8 |character |Logos alt 8. |
#' |logos_rel_full_8 |character |Logos rel full 8. |
#' |logos_rel_primary_logo_black |character |Logos rel primary logo black. |
#' |logos_last_updated_8 |character |Logos last updated 8. |
#' |logos_href_9 |character |Logos href 9. |
#' |logos_width_9 |integer |Logos width 9. |
#' |logos_height_9 |integer |Logos height 9. |
#' |logos_alt_9 |character |Logos alt 9. |
#' |logos_rel_full_9 |character |Logos rel full 9. |
#' |logos_rel_primary_logo_white |character |Logos rel primary logo white. |
#' |logos_last_updated_9 |character |Logos last updated 9. |
#' ...and 212 further ESPN stat columns (full batting / pitching / fielding stat set).
#'
#' @importFrom jsonlite fromJSON toJSON
#' @importFrom dplyr filter select rename bind_cols bind_rows
#' @importFrom tidyr unnest unnest_wider everything
#' @export
#' @keywords MLB Team Stats
#' @family ESPN MLB Functions
#'
#' @examples
#' \donttest{
#' try(espn_mlb_team_stats(team_id = 13, year = 2020))
#' }
espn_mlb_team_stats <- function(
team_id,
year,
season_type = "regular",
total = FALSE) {
.args <- mget(setdiff(names(formals()), "..."))
if (!(tolower(season_type) %in% c("regular", "postseason"))) {
# Check if season_type is appropriate, if not regular
cli::cli_abort("Enter valid season_type: regular or postseason")
}
s_type <- ifelse(season_type == "postseason", 3, 2)
base_url <- "https://sports.core.api.espn.com/v2/sports/baseball/leagues/mlb/seasons/"
totals <- ifelse(total == TRUE, 0, "")
full_url <- paste0(
base_url,
year,
"/types/",
s_type,
"/teams/",
team_id,
"/statistics/",
totals
)
df <- data.frame()
tryCatch(
expr = {
# Create the GET request and set response as res
res <- .retry_request(full_url)
# Check the result
check_status(res)
# Get the content and return result as data.frame
df <- res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
team_url <- df[["team"]][["$ref"]]
# Create the GET request and set response as res
team_res <- .retry_request(team_url)
# Check the result
check_status(team_res)
team_df <- team_res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
team_df[["links"]] <- NULL
team_df[["injuries"]] <- NULL
team_df[["record"]] <- NULL
team_df[["athletes"]] <- NULL
team_df[["venue"]] <- NULL
team_df[["groups"]] <- NULL
team_df[["ranks"]] <- NULL
team_df[["statistics"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["links"]] <- NULL
team_df[["notes"]] <- NULL
team_df[["franchise"]] <- NULL
team_df[["againstTheSpreadRecords"]] <- NULL
team_df[["oddsRecords"]] <- NULL
team_df[["college"]] <- NULL
team_df[["transactions"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["depthCharts"]] <- NULL
team_df[["awards"]] <- NULL
team_df[["events"]] <- NULL
team_df <- team_df %>%
purrr::map_if(is.list, as.data.frame) %>%
as.data.frame() %>%
dplyr::select(
-dplyr::any_of(
c(
"logos.width",
"logos.height",
"logos.alt",
"logos.rel..full.",
"logos.rel..default.",
"logos.rel..scoreboard.",
"logos.rel..scoreboard..1",
"logos.rel..scoreboard.2",
"logos.lastUpdated",
"logos.width.1",
"logos.height.1",
"logos.alt.1",
"logos.rel..full..1",
"logos.rel..dark.",
"logos.rel..dark..1",
"logos.lastUpdated.1",
"logos.width.2",
"logos.height.2",
"logos.alt.2",
"logos.rel..full..2",
"logos.rel..scoreboard.",
"logos.lastUpdated.2",
"logos.width.3",
"logos.height.3",
"logos.alt.3",
"logos.rel..full..3",
"logos.lastUpdated.3",
"X.ref",
"X.ref.1",
"X.ref.2"
)
)
) %>%
janitor::clean_names()
colnames(team_df)[1:13] <- paste0("team_", colnames(team_df)[1:13])
team_df <- team_df %>%
dplyr::rename(
"logo_href" = "logos_href",
"logo_dark_href" = "logos_href_1"
)
df <- res %>%
.resp_text() %>%
jsonlite::fromJSON() %>%
purrr::pluck("splits") %>%
purrr::pluck("categories") %>%
tidyr::unnest("stats", names_sep = "_")
df <- df %>%
dplyr::mutate(
stats_category_name = paste0(.data$name, "_", .data$stats_name)
) %>%
dplyr::select(
"stats_category_name",
"stats_value"
) %>%
tidyr::pivot_wider(
names_from = "stats_category_name",
values_from = "stats_value",
values_fn = dplyr::first
) %>%
janitor::clean_names()
df <- team_df %>%
dplyr::bind_cols(df)
df <- df %>%
dplyr::mutate_at(
c(
"team_id"
),
as.integer
) %>%
make_baseballr_data("ESPN MLB Team Season Stats from ESPN.com", Sys.time())
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no team season stats data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(df)
}
#' @title
#' **Get ESPN MLB player stats data**
#' @author Saiem Gilani
#' @param athlete_id Athlete ID
#' @param year Year
#' @param season_type (character, default: regular): Season type - regular or postseason
#' @param total (boolean, default: FALSE): Totals
#' @return Returns a tibble with the player stats data
#'
#'
#' |col_name |types |description |
#' |:--------|:-----|:-----------|
#' |athlete_id |integer |Unique ESPN athlete identifier. |
#' |athlete_uid |character |Athlete uid. |
#' |athlete_guid |character |Athlete guid. |
#' |athlete_type |character |Athlete type. |
#' |sdr |integer |Sdr. |
#' |first_name |character |First name. |
#' |last_name |character |Last name. |
#' |full_name |character |Full name. |
#' |display_name |character |Display name. |
#' |nickname |character |Team nickname. |
#' |short_name |character |Short display name. |
#' |weight |numeric |Weight. |
#' |display_weight |character |Display weight. |
#' |height |numeric |Height. |
#' |display_height |character |Display height. |
#' |age |integer |Age. |
#' |date_of_birth |character |Date of birth. |
#' |debut_year |integer |Debut year. |
#' |slug |character |Slug. |
#' |headshot_href |character |Headshot href. |
#' |headshot_alt |character |Headshot alt. |
#' |jersey |character |Jersey. |
#' |position_id |integer |Position id. |
#' |position_name |character |Position name. |
#' |position_display_name |character |Position display name. |
#' |position_abbreviation |character |Position abbreviation. |
#' |position_leaf |logical |Position leaf. |
#' |positions_x_ref |character |Positions x ref. |
#' |positions_id |character |Positions id. |
#' |positions_name |character |Positions name. |
#' |positions_display_name |character |Positions display name. |
#' |positions_abbreviation |character |Positions abbreviation. |
#' |positions_leaf |logical |Positions leaf. |
#' |positions_x_ref_1 |character |Positions x ref 1. |
#' |positions_x_ref_2 |character |Positions x ref 2. |
#' |positions_x_ref_3 |character |Positions x ref 3. |
#' |positions_id_1 |character |Positions id 1. |
#' |positions_name_1 |character |Positions name 1. |
#' |positions_display_name_1 |character |Positions display name 1. |
#' |positions_abbreviation_1 |character |Positions abbreviation 1. |
#' |positions_leaf_1 |logical |Positions leaf 1. |
#' |positions_x_ref_4 |character |Positions x ref 4. |
#' |positions_x_ref_5 |character |Positions x ref 5. |
#' |positions_x_ref_6 |character |Positions x ref 6. |
#' |positions_id_2 |character |Positions id 2. |
#' |positions_name_2 |character |Positions name 2. |
#' |positions_display_name_2 |character |Positions display name 2. |
#' |positions_abbreviation_2 |character |Positions abbreviation 2. |
#' |positions_leaf_2 |logical |Positions leaf 2. |
#' |positions_x_ref_7 |character |Positions x ref 7. |
#' |positions_x_ref_8 |character |Positions x ref 8. |
#' |positions_x_ref_9 |character |Positions x ref 9. |
#' |positions_id_3 |character |Positions id 3. |
#' |positions_name_3 |character |Positions name 3. |
#' |positions_display_name_3 |character |Positions display name 3. |
#' |positions_abbreviation_3 |character |Positions abbreviation 3. |
#' |positions_leaf_3 |logical |Positions leaf 3. |
#' |positions_x_ref_10 |character |Positions x ref 10. |
#' |positions_x_ref_11 |character |Positions x ref 11. |
#' |linked |logical |Linked. |
#' ...and 216 further ESPN stat columns (full batting / pitching / fielding stat set).
#'
#' @export
#' @keywords MLB Player Stats
#' @family ESPN MLB Functions
#' @examples
#' \donttest{
#' try(espn_mlb_player_stats(athlete_id = 33192, year = 2022))
#' }
espn_mlb_player_stats <- function(
athlete_id,
year,
season_type = "regular",
total = FALSE) {
.args <- mget(setdiff(names(formals()), "..."))
if (!(tolower(season_type) %in% c("regular", "postseason"))) {
# Check if season_type is appropriate, if not regular
cli::cli_abort("Enter valid season_type: regular or postseason")
}
s_type <- ifelse(season_type == "postseason", 3, 2)
base_url <- "https://sports.core.api.espn.com/v2/sports/baseball/leagues/mlb/seasons/"
totals <- ifelse(total == TRUE, 0, "")
full_url <- paste0(
base_url,
year,
"/types/",
s_type,
"/athletes/",
athlete_id,
"/statistics/",
totals
)
athlete_url <- paste0(
base_url,
year,
"/athletes/",
athlete_id
)
df <- data.frame()
tryCatch(
expr = {
# Create the GET request and set response as res
res <- .retry_request(full_url)
# Check the result
check_status(res)
# Create the GET request and set response as res
athlete_res <- .retry_request(athlete_url)
# Check the result
check_status(athlete_res)
athlete_df <- athlete_res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
team_url <- athlete_df[["team"]][["$ref"]]
# Create the GET request and set response as res
team_res <- .retry_request(team_url)
# Check the result
check_status(team_res)
team_df <- team_res %>%
.resp_text() %>%
jsonlite::fromJSON(
simplifyDataFrame = FALSE,
simplifyVector = FALSE,
simplifyMatrix = FALSE
)
team_df[["links"]] <- NULL
team_df[["injuries"]] <- NULL
team_df[["record"]] <- NULL
team_df[["athletes"]] <- NULL
team_df[["venue"]] <- NULL
team_df[["groups"]] <- NULL
team_df[["ranks"]] <- NULL
team_df[["statistics"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["links"]] <- NULL
team_df[["notes"]] <- NULL
team_df[["franchise"]] <- NULL
team_df[["againstTheSpreadRecords"]] <- NULL
team_df[["oddsRecords"]] <- NULL
team_df[["college"]] <- NULL
team_df[["transactions"]] <- NULL
team_df[["leaders"]] <- NULL
team_df[["depthCharts"]] <- NULL
team_df[["awards"]] <- NULL
team_df[["events"]] <- NULL
team_df <- team_df %>%
purrr::map_if(is.list, as.data.frame) %>%
as.data.frame() %>%
dplyr::select(
-dplyr::any_of(
c(
"logos.width",
"logos.height",
"logos.alt",
"logos.rel..full.",
"logos.rel..default.",
"logos.rel..scoreboard.",
"logos.rel..scoreboard..1",
"logos.rel..scoreboard.2",
"logos.lastUpdated",
"logos.width.1",
"logos.height.1",
"logos.alt.1",
"logos.rel..full..1",
"logos.rel..dark.",
"logos.rel..dark..1",
"logos.lastUpdated.1",
"logos.width.2",
"logos.height.2",
"logos.alt.2",
"logos.rel..full..2",
"logos.rel..scoreboard.",
"logos.lastUpdated.2",
"logos.width.3",
"logos.height.3",
"logos.alt.3",
"logos.rel..full..3",
"logos.lastUpdated.3",
"X.ref",
"X.ref.1",
"X.ref.2"
)
)
) %>%
janitor::clean_names()
colnames(team_df)[1:13] <- paste0("team_", colnames(team_df)[1:13])
team_df <- team_df %>%
dplyr::rename(
"logo_href" = "logos_href",
"logo_dark_href" = "logos_href_1"
)
athlete_df[["links"]] <- NULL
athlete_df[["injuries"]] <- NULL
athlete_df[["birthPlace"]] <- NULL
athlete_df <- athlete_df %>%
purrr::map_if(is.list, as.data.frame) %>%
tibble::tibble(data = .data$.)
athlete_df <- athlete_df$data %>%
as.data.frame() %>%
dplyr::select(
-dplyr::any_of(c(
"X.ref",
"X.ref.1",
"X.ref.2",
"X.ref.3",
"X.ref.4",
"X.ref.5",
"X.ref.6",
"X.ref.7",
"X.ref.8",
"position.X.ref",
"position.X.ref.1",
"contract.x.ref",
"contract.x.ref.1",
"contract.x.ref.2",
"draft.x.ref",
"draft.x.ref.1"
))
) %>%
janitor::clean_names() %>%
dplyr::rename(
"athlete_id" = "id",
"athlete_uid" = "uid",
"athlete_guid" = "guid",
"athlete_type" = "type"
)
# Get the content and return result as data.frame
df <- res %>%
.resp_text() %>%
jsonlite::fromJSON() %>%
purrr::pluck("splits") %>%
purrr::pluck("categories") %>%
tidyr::unnest("stats", names_sep = "_")
df <- df %>%
dplyr::mutate(
stats_category_name = paste0(.data$name, "_", .data$stats_name)
) %>%
dplyr::select("stats_category_name", "stats_value") %>%
tidyr::pivot_wider(
names_from = "stats_category_name",
values_from = "stats_value",
values_fn = dplyr::first
) %>%
janitor::clean_names()
df <- athlete_df %>%
dplyr::bind_cols(df) %>%
dplyr::bind_cols(team_df)
df <- df %>%
dplyr::mutate_at(
c(
"athlete_id",
"team_id",
"position_id",
"status_id",
"sdr"
),
as.integer
) %>%
make_baseballr_data(
"ESPN MLB Player Season Stats from ESPN.com",
Sys.time()
)
},
error = function(e) .report_api_error(
e,
hint = "Invalid arguments or no player season stats data available!",
args = .args
),
warning = function(w) {},
finally = {}
)
return(df)
}
#' **Parse ESPN MLB PBP, helper function**
#' @param resp Response object from the ESPN MLB game summary endpoint
#' @return Returns a tibble
#' @importFrom lubridate with_tz ymd_hm
#' @keywords internal
#' @export
helper_espn_mlb_pbp <- function(resp) {
game_json <- resp %>%
jsonlite::fromJSON()
pbp_source <- game_json[["header"]][["competitions"]][["playByPlaySource"]]
plays <- game_json %>%
purrr::pluck("plays") %>%
dplyr::as_tibble()
if (pbp_source != "none" && nrow(plays) > 10) {
homeAway1 <- jsonlite::fromJSON(resp)[["header"]][["competitions"]][[
"competitors"
]][[1]][["homeAway"]][1]
gameId <- as.integer(game_json[["header"]][["id"]])
season <- game_json[["header"]][["season"]][["year"]]
season_type <- game_json[["header"]][["season"]][["type"]]
game_date_time <- substr(
game_json[["header"]][["competitions"]][["date"]],
1,
nchar(game_json[["header"]][["competitions"]][["date"]]) - 1
) %>%
lubridate::ymd_hm() %>%
lubridate::with_tz(tzone = "America/New_York")
game_date <- as.Date(substr(game_date_time, 0, 10))
id_vars <- data.frame()
if (homeAway1 == "home") {
homeTeamId <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"team"
]][["id"]] %>%
purrr::pluck(1, .default = NA_integer_)
)
homeTeamMascot <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["name"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamName <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["location"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamAbbrev <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["abbreviation"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamLogo <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["logos"]][[1]][["href"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamLogoDark <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["logos"]][[1]][["href"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamFullName <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["displayName"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["color"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamAlternateColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["alternateColor"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamScore <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"score"
]] %>%
purrr::pluck(1, .default = NA_character_)
)
homeTeamWinner <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["winner"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamRecord <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["record"]][[1]][["summary"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamId <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"team"
]][["id"]] %>%
purrr::pluck(2, .default = NA_integer_)
)
awayTeamMascot <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["name"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamName <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["location"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamAbbrev <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["abbreviation"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamLogo <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["logos"]][[2]][["href"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamLogoDark <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["logos"]][[2]][["href"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamFullName <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["displayName"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["color"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamAlternateColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["alternateColor"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamScore <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"score"
]] %>%
purrr::pluck(2, .default = NA_integer_)
)
awayTeamWinner <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["winner"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamRecord <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["record"]][[1]][["summary"]] %>%
purrr::pluck(2, .default = NA_character_)
id_vars <- data.frame(
homeTeamId,
homeTeamMascot,
homeTeamName,
homeTeamAbbrev,
homeTeamLogo,
homeTeamLogoDark,
homeTeamFullName,
homeTeamColor,
homeTeamAlternateColor,
homeTeamScore,
homeTeamWinner,
homeTeamRecord,
awayTeamId,
awayTeamMascot,
awayTeamName,
awayTeamAbbrev,
awayTeamLogo,
awayTeamLogoDark,
awayTeamFullName,
awayTeamColor,
awayTeamAlternateColor,
awayTeamScore,
awayTeamWinner,
awayTeamRecord
)
} else {
awayTeamId <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"team"
]][["id"]] %>%
purrr::pluck(1, .default = NA_integer_)
)
awayTeamMascot <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["name"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamName <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["location"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamAbbrev <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["abbreviation"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamLogo <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["logos"]][[1]][["href"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamLogoDark <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["logos"]][[1]][["href"]] %>%
purrr::pluck(2, .default = NA_character_)
awayTeamFullName <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["displayName"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["color"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamAlternateColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["alternateColor"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamScore <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"score"
]] %>%
purrr::pluck(1, .default = NA_integer_)
)
awayTeamWinner <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["winner"]] %>%
purrr::pluck(1, .default = NA_character_)
awayTeamRecord <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["record"]][[1]][["summary"]] %>%
purrr::pluck(1, .default = NA_character_)
homeTeamId <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"team"
]][["id"]] %>%
purrr::pluck(2, .default = NA_integer_)
)
homeTeamMascot <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["name"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamName <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["location"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamAbbrev <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["abbreviation"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamLogo <- game_json[["header"]][["competitions"]][["competitors"]][[
1
]][["team"]][["logos"]][[2]][["href"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamLogoDark <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["logos"]][[2]][["href"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamFullName <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["displayName"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["color"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamAlternateColor <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["team"]][["alternateColor"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamScore <- as.integer(
game_json[["header"]][["competitions"]][["competitors"]][[1]][[
"score"
]] %>%
purrr::pluck(2, .default = NA_integer_)
)
homeTeamWinner <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["winner"]] %>%
purrr::pluck(2, .default = NA_character_)
homeTeamRecord <- game_json[["header"]][["competitions"]][[
"competitors"
]][[1]][["record"]][[1]][["summary"]] %>%
purrr::pluck(2, .default = NA_character_)
id_vars <- data.frame(
homeTeamId,
homeTeamMascot,
homeTeamName,
homeTeamAbbrev,
homeTeamLogo,
homeTeamLogoDark,
homeTeamFullName,
homeTeamColor,
homeTeamAlternateColor,
homeTeamScore,
homeTeamWinner,
homeTeamRecord,
awayTeamId,
awayTeamMascot,
awayTeamName,
awayTeamAbbrev,
awayTeamLogo,
awayTeamLogoDark,
awayTeamFullName,
awayTeamColor,
awayTeamAlternateColor,
awayTeamScore,
awayTeamWinner,
awayTeamRecord
)
}
game_json <- game_json %>%
jsonlite::toJSON() %>%
jsonlite::fromJSON(flatten = TRUE)
plays <- game_json %>%
purrr::pluck("plays")
# (No court-coordinate transform: ESPN baseball play-by-play carries
# pitch and batted-ball locations as pitchCoordinate / hitCoordinate,
# which are flattened to pitch_coordinate_x/y and hit_coordinate_x/y
# below -- there is no single top-level shot coordinate to transform.)
## Written this way for compliance with data repository processing
if ("participants" %in% names(plays)) {
plays <- plays %>%
tidyr::unnest_wider("participants")
suppressWarnings(
aths <- plays %>%
dplyr::group_by(.data$id) %>%
dplyr::select(
"id",
"athlete.id"
) %>%
tidyr::unnest_wider("athlete.id", names_sep = "_")
)
names(aths) <- c(
"play.id",
"athlete.id.1",
"athlete.id.2",
"athlete.id.3"
)
plays <- plays %>%
dplyr::bind_cols(aths) %>%
janitor::clean_names() %>%
dplyr::mutate(dplyr::across(
dplyr::any_of(c(
"athlete_id_1",
"athlete_id_2",
"athlete_id_3"
)),
~ as.integer(.x)
))
}
## Written this way for compliance with data repository processing
if (!("homeTeamName" %in% names(plays))) {
plays <- plays %>%
dplyr::bind_cols(id_vars)
}
plays <- plays %>%
dplyr::select(-dplyr::any_of(c("athlete.id", "athlete_id"))) %>%
janitor::clean_names() %>%
# Drop any unnamed/auto-repaired column (tibble turns an empty JSON field
# name into "...N", which clean_names() renames to "xN").
dplyr::select(-dplyr::matches("^x[0-9]+$")) %>%
dplyr::mutate(
game_id = gameId,
season = season,
season_type = season_type,
game_date = game_date,
game_date_time = game_date_time
) %>%
dplyr::rename(dplyr::any_of(c(
"athlete_id_1" = "participants_0_athlete_id",
"athlete_id_2" = "participants_1_athlete_id",
"athlete_id_3" = "participants_2_athlete_id"
)))
plays <- plays %>%
dplyr::mutate(dplyr::across(
dplyr::any_of(c(
"athlete_id_1",
"athlete_id_2",
"athlete_id_3",
"type_id",
"team_id"
)),
~ as.integer(.x)
))
plays_df <- plays %>%
make_baseballr_data(
"ESPN MLB Play-by-Play Information from ESPN.com",
Sys.time()
)
return(plays_df)
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.