knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" )
The goal of rlolesports is to enable easy queries of the unofficial Riot Games Esports API for League of Legends. It is very much a package in development, not yet tested extensively.
The package offers very much opinionated data processing of the original
JSON returns of the API. Thus, every user-facing function has a variable
save_details
, which can be set to TRUE
to return the original and unparsed
query result. Without the flag, functions are built to return lists or data.frames
for easy processing in the dplyr
universe.
You can install the current version from GitHub with:
# install.packages("remotes") remotes::install_github("flsck/rlolesports")
First, we use get_leagues()
without any parameter to create a list of
leagues for which data can be queried.
library(rlolesports) leagues <- get_leagues() # head(leagues[,1:4], 10)
We'll try to get some data for a match played in the LEC, so we'll filter
the data.frame of leagues and find the ID of the LEC. (Of course, there are
many ways to achieve this. Below is just a dplyr
way.)
# Extract the ID of the LEC lec_id <- leagues %>% dplyr::filter(name == "LEC") %>% dplyr::select(id) %>% purrr::pluck(1) # print(paste0("The ID of the LEC is: ", lec_id))
To get a bit ahead of myself: The function get_tournaments_for_league(...)
returns all available
splits or general tournaments for a given league. The ids gathered by this function however are NOT
used when finding a leagues's schedule, that the leagueId's job, which we already have!
The query below will help us later - because it allows us to find the starting date of a specific
split.
# Get the ID and dates for tournaments in the LEC tourney <- get_tournaments_for_league(leagueId = lec_id) # head(tourney) # Extract the ID of the 2021 spring split of the LEC lec_spring_id <- tourney %>% dplyr::filter(slug == "lec_2021_split1") %>% dplyr::select(id) %>% dplyr::pull(1)
This gives us the available schedule for all of LEC. This is not optimal,
because we now need to filter this schedule by the column startTime
, where we
need to find a specific condition by ourselves. We utilize the tourney
data.frame
from above to find the starting date of the LEC 2021 spring split.
lec_schedule <- get_schedule(lec_id) # So we grab the respective date from our tournament data.frame! spring_starting_date <- dplyr::filter(tourney, id == lec_spring_id) %>% dplyr::select(startDate) %>% purrr::pluck(1) # ... and filter the schedule based on the matches starting times! lec_spring_schedule <- dplyr::filter(lec_schedule, as.Date(startTime) >= spring_starting_date) # head(lec_spring_schedule)
Next, we juggle some IDs - match and game IDs, to be precise. To get details of a game, such as
Gold, CS, kills, etc. we need the gameId
. The schedule above however returns a matchId
, which
contains different gameId
entries.
To illustrate this further, think about a best-of-5 series between G2 and MAD Lions. The series itself
is one match with one matchId
. The games within that series however all have different gameId
variables, which we would use to get more details about one specific game in the series.
Below, we will just grab the gameId
of the best-of-1 match between G2 and MAD that opened the
2021 LEC spring split.
# Next, we get the ID of the opening match, the first row in the data.frame! opening_match <- lec_spring_schedule$match.id[1] # but the matchId is not the gameId we need for detailed queries of match details, # which is why we need to grab details of the match, where the respective gameId is saved. opening_details <- get_event_details(opening_match) opening_game_id <- opening_details$games$game_id[1]
With the gameId
as a variable, we can get detailed information about the match
by calling get_complete_window()
.
g2_vs_mad <- get_complete_window(opening_game_id) # print(g2_vs_mad$data[2500:2510,])
That's it. Now we have data for the game and could analyze, for example, the time series of totalGold. Below is just a possible graphical illustration of the total gold difference over time. Note that we have not adressed the time axis, which is not currently gametime, but just the UTC time.
# Since the data.frame returns one row per team member per team, we need to extract just # one row for a given timestamp and team for the aggregated statistics, like totalGold and # totalKills. library(dplyr, verbose=FALSE) plot_df <- g2_vs_mad$data %>% group_by(timestamp, team) %>% select(totalGold, totalKills, timestamp, team) %>% slice_head() %>% arrange(timestamp) %>% distinct(timestamp, team, .keep_all = TRUE) %>% ungroup() plot_df <- plot_df %>% select(timestamp, totalGold, team) %>% tidyr::pivot_wider(names_from = team, values_from = totalGold) %>% mutate(blue_diff = as.double(blue - red), blue_lead = as.factor(sign(blue_diff)), y_min = if_else(blue_diff > 0, 0, blue_diff), y_max = if_else(blue_diff > 0, blue_diff, 0), timestamp = lubridate::ymd_hms(timestamp)) %>% distinct(timestamp, .keep_all = TRUE) %>% tidyr::complete(blue_lead, timestamp, fill = list(blue_diff = 0)) library(ggplot2, verbose=FALSE) plot_df %>% ggplot(aes(x = timestamp, y = blue_diff, color = blue_lead)) + geom_ribbon(data = filter(plot_df, blue_diff <= 0), aes(ymax = y_max, ymin = y_min, fill = blue_lead, color = blue_lead), outline.type = "lower" ) + geom_ribbon(data = filter(plot_df, blue_diff >= 0), aes(ymax = y_max, ymin = y_min, fill = blue_lead, color = blue_lead), outline.type = "upper" ) + scale_color_manual(values = c("red", "black", "blue")) + ylim(c(-2500, max(plot_df$blue_diff))) + xlab("") + ylab("") + ggtitle("Gold Difference between G2 (blue) and MAD (red)") + theme(legend.position = "none", panel.background = element_rect(fill = "darkgrey"), plot.background = element_rect(fill = "darkgrey"), panel.grid = element_line(colour = "darkgrey"), title = element_text())
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.