NHL API: Get Game Logs
Introduction
The NHL has a publicly accessible Application Programming Interface (or API) that allows users to obtain a lot of useful data (including detailed play-by-play data). There are a couple of obstacles though: 1) the NHL API does not come with a user manual; and 2) the NHL API is most easily accessed using a programming language such as R or Python. To help you overcome those obstacles I’m writing articles that provide the code (in the R programming language) for functions that pull data from the NHL API.
In this article I provide a function that pulls a skater’s regular season game logs.
The Data
Before I provide the code, here’s a sample of the data.
player_id: 8478402
player: Connor McDavid
season: 20222023
game_id: 2022021308
date: 2023-04-13
toi_as: 916
toi_es: 673
toi_pp: 232
toi_sh: 11
goals: 0
assists: 1
points: 1
shots: 5
hits: 0
blocks: 1
pim: 0
goals_es: 0
goals_pp: 0
goals_sh: 0
goals_ot: 0
assists_es: 0
assists_pp: 1
assists_sh: 0
points_pp: 1
points_sh: 0
shooting_pct: 0
face_off_pct: 75
team_id: 22
team_name: Edmonton Oilers
opponent_id: 8
opponent_name: San Jose Sharks
is_home: TRUE
is_win: TRUE
is_ot: FALSE
The Code
Here’s the code for the function that pulls the above data.
# This function pulls a player's game logs for a specified season
# SKATERS ONLY
# REGULAR SEASON ONLY
# Time-on-ice data is returned as seconds
# Use my get_team_rosters() function to find player_ids
# The season format is YEARYEAR (for example 20222023)
# Wrap this function in a loop to pull data for multiple players at the same time (see EXAMPLE on GitHub)
get_game_logs <- function(player_id, season) {
# Get the player's full name
player_site <- read_json(paste0("https://statsapi.web.nhl.com/api/v1/people/", player_id))
player_name <- player_site$people %>%
tibble() %>%
unnest_wider(1)
player_name <- player_name$fullName
# Pull and organize the raw game log data
gl_site <- read_json(paste0("https://statsapi.web.nhl.com/api/v1/people/", player_id, "/stats/?stats=gameLog&season=", season))
stats <- gl_site$stats %>%
tibble() %>%
unnest_wider(1)
stats <- stats$splits %>%
tibble() %>%
unnest_longer(1) %>%
unnest_wider(1) %>%
unnest_wider(stat) %>%
unnest_wider(team) %>%
rename(team_id = id,
team_name = name,
team_link = link) %>%
unnest_wider(opponent) %>%
rename(opponent_id = id,
opponent_name = name,
opponent_link = link) %>%
unnest_wider(game)
# Add special teams assists data
stats <- mutate(stats, player_id = player_id,
player = player_name,
assists_pp = powerPlayPoints - powerPlayGoals,
assists_sh = shortHandedPoints - shortHandedGoals)
# Add even strength scoring data
stats <- mutate(stats, goals_es = goals - (powerPlayGoals + shortHandedGoals),
assists_es = assists - (assists_pp + assists_sh))
# Select the data to be returned by the function
stats <- select(stats, player_id,
player,
season,
game_id = gamePk,
date,
toi_as = timeOnIce,
toi_es = evenTimeOnIce,
toi_pp = powerPlayTimeOnIce,
toi_sh = shortHandedTimeOnIce,
goals,
assists,
points,
shots,
hits,
blocks = blocked,
pim,
goals_es,
goals_pp = powerPlayGoals,
goals_sh = shortHandedGoals,
goals_ot = overTimeGoals,
assists_es,
assists_pp,
assists_sh,
points_pp = powerPlayPoints,
points_sh = shortHandedPoints,
shooting_pct = shotPct,
face_off_pct = faceOffPct,
team_id,
team_name,
opponent_id,
opponent_name,
is_home = isHome,
is_win = isWin,
is_ot = isOT)
# Final clean up for date/time
stats$date <- as.Date(stats$date)
stats$toi_as <- ms(stats$toi_as)
stats$toi_as <- period_to_seconds(stats$toi_as)
stats$toi_es <- ms(stats$toi_es)
stats$toi_es <- period_to_seconds(stats$toi_es)
stats$toi_pp <- ms(stats$toi_pp)
stats$toi_pp <- period_to_seconds(stats$toi_pp)
stats$toi_sh <- ms(stats$toi_sh)
stats$toi_sh <- period_to_seconds(stats$toi_sh)
return(stats)
}
Get It On GitHub
I’ve created a public repository on GitHub where I’ll be sharing my functions for accessing the NHL’s API. You can go to the repository by clicking here.
The End Of The Article
That’s the end of this article. Follow me on twitter to be notified about new content.
Cheers,
Mark (18 Skaters)