NHL API: Get NHL Career Stats
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 NHL career stats.
The Data
Before I provide the code, here’s a sample of the data.
player_id: 8478402
player: Connor McDavid
gp: 569
toi_as: 742323
toi_es: 600275
toi_pp: 119736
toi_sh: 22312
goals: 303
assists: 547
points: 850
shots: 1948
hits: 375
blocks: 223
pim: 219
goals_es: 225
goals_pp: 71
goals_sh: 7
goals_ot: 15
assists_es: 320
assists_pp: 218
assists_sh: 9
points_pp: 289
points_sh: 16
shooting_pct: 15.6
The Code
Here’s the code for the function that pulls the above data.
# This function pulls a player's NHL career stats
# SKATERS ONLY
# REGULAR SEASON
# Time-on-ice data is returned as seconds
# Use my get_team_rosters() function to find player_ids
# Wrap this function in a loop to pull data for multiple players at the same time (see EXAMPLE on GitHub)
get_career_stats <- function(player_id) {
# 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 data
yby_site <- read_json(paste0("https://statsapi.web.nhl.com/api/v1/people/", player_id, "/stats/?stats=yearByYear"))
stats <- yby_site$stats %>%
tibble() %>%
unnest_wider(1)
stats <- stats$splits %>%
tibble() %>%
unnest(1) %>%
unnest_wider(1) %>%
unnest_wider(stat) %>%
unnest_wider(team, names_sep = "_") %>%
unnest_wider(league, names_sep = "_")
# Add special teams assists data
stats <- mutate(stats, 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))
# Clean up for time
stats$timeOnIce <- ms(stats$timeOnIce, quiet = TRUE)
stats$timeOnIce <- period_to_seconds(stats$timeOnIce)
stats$evenTimeOnIce <- ms(stats$evenTimeOnIce, quiet = TRUE)
stats$evenTimeOnIce <- period_to_seconds(stats$evenTimeOnIce)
stats$powerPlayTimeOnIce <- ms(stats$powerPlayTimeOnIce, quiet = TRUE)
stats$powerPlayTimeOnIce <- period_to_seconds(stats$powerPlayTimeOnIce)
stats$shortHandedTimeOnIce <- ms(stats$shortHandedTimeOnIce, quiet = TRUE)
stats$shortHandedTimeOnIce <- period_to_seconds(stats$shortHandedTimeOnIce)
# Filter for only NHL data
stats <- filter(stats, league_id == 133)
# Sum the data for each stat
stats <- summarise(stats, gp = sum(games),
toi_as = sum(timeOnIce),
toi_es = sum(evenTimeOnIce),
toi_pp = sum(powerPlayTimeOnIce),
toi_sh = sum(shortHandedTimeOnIce),
goals = sum(goals),
assists = sum(assists),
points = sum(points),
shots = sum(shots),
hits = sum(hits),
blocks = sum(blocked),
pim = sum(pim),
goals_es = sum(goals_es),
goals_pp = sum(powerPlayGoals),
goals_sh = sum(shortHandedGoals),
goals_ot = sum(overTimeGoals),
assists_es = sum(assists_es),
assists_pp = sum(assists_pp),
assists_sh = sum(assists_sh),
points_pp = sum(powerPlayPoints),
points_sh = sum(shortHandedPoints))
# Add career shooting percentage
stats <- mutate(stats, shooting_pct = round((goals / shots) * 100, 1))
# Add player data
stats <- mutate(stats, player_id = player_id,
player = player_name)
# Rearrange the data to be returned by the function
stats <- select(stats, c(23:24,1:22))
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)