Skip to contents
library(tRakt)
library(tibble) # For glimpse()

Use the search function to find the show you’re looking for.

show_info <- search_query("24", type = "show")
show_info
#> # A tibble: 1 × 9
#>   type  score title          year trakt  slug          tvdb   imdb       tmdb  
#>   <chr> <dbl> <chr>         <int> <chr>  <chr>         <chr>  <chr>      <chr> 
#> 1 show   221. Yakamoz S-245  2022 194241 yakamoz-s-245 394252 tt13317454 195930

Step 2: Use the ID

Use the trakt ID (recommended over other IDs) for subsequent API calls.
In this case, we’ll use seasons_summary() to get data for all seasons of the show, while also getting an additional list-column containing all episode data, which includes user ratings.

seasons <- seasons_summary(show_info$trakt, extended = "full", episodes = TRUE)
glimpse(seasons)
#> Rows: 1
#> Columns: 14
#> $ season         <int> 1
#> $ rating         <dbl> 6.30303
#> $ votes          <int> 33
#> $ episode_count  <int> 7
#> $ aired_episodes <int> 7
#> $ title          <chr> "Season 1"
#> $ overview       <chr> "After disaster strikes Earth, a marine biologist on a …
#> $ first_aired    <dttm> 2022-04-20 07:00:00
#> $ updated_at     <dttm> 2024-10-01 08:41:43
#> $ network        <chr> "Netflix"
#> $ episodes       <list> [<tbl_df[7 x 17]>]
#> $ trakt          <chr> "290166"
#> $ tvdb           <chr> NA
#> $ tmdb           <chr> "284769"

Step 3: Tidying up

We’re interested in the episodes list-column, which needs unnesting. In this case we can simply use dplyr::bind_rows to take the list of tbls that is seasons$episodes and basically rbind them all together, meaning the result is a tibble of the episode data we care about.

library(dplyr)

episodes <- bind_rows(seasons$episodes)
glimpse(episodes)
#> Rows: 7
#> Columns: 17
#> $ season                 <int> 1, 1, 1, 1, 1, 1, 1
#> $ episode                <int> 1, 2, 3, 4, 5, 6, 7
#> $ title                  <chr> "Episode 1", "Episode 2", "Episode 3", "Episode…
#> $ episode_abs            <lgl> NA, NA, NA, NA, NA, NA, NA
#> $ overview               <chr> "Arman reluctantly embarks on a submarine resea…
#> $ rating                 <dbl> 6.88722, 6.95238, 7.02000, 7.24419, 7.07143, 7.…
#> $ votes                  <int> 133, 105, 100, 86, 84, 80, 84
#> $ comment_count          <int> 1, 0, 1, 0, 1, 1, 1
#> $ first_aired            <dttm> 2022-04-20 07:00:00, 2022-04-20 07:00:00, 2022-…
#> $ updated_at             <dttm> 2024-09-30 03:39:05, 2024-10-01 00:47:48, 2024-…
#> $ available_translations <list> <"cs", "de", "el", "en", "fr", "it", "ko", "pl"…
#> $ runtime                <int> 46, 44, 41, 51, 50, 54, 50
#> $ episode_type           <chr> "series_premiere", "standard", "standard", "sta…
#> $ trakt                  <chr> "5990234", "6014174", "6014175", "6014176", "60…
#> $ tvdb                   <chr> "8209034", "8209035", "8209036", "8209037", "8…
#> $ imdb                   <chr> "tt13840052", "tt13840054", "tt13840058", "tt1…
#> $ tmdb                   <chr> "3617839", "3640494", "3640495", "3640496", "3…

Step 4: Graph!

Now we have our episode data in a tidy form, might as well look at it.

library(ggplot2)

ggplot(data = episodes, aes(x = episode, y = rating, color = votes)) +
  geom_point(size = 3, alpha = 2 / 3) +
  facet_wrap(~season, nrow = 1, scales = "free_x") +
  scale_x_continuous(breaks = c(1, 10, 20), expand = c(0, 3)) +
  scale_y_continuous(breaks = seq(0, 10, .5), minor_breaks = seq(0, 10, .25), limits = c(7, 9)) +
  scale_color_viridis_c() +
  guides(color = guide_colorbar(barwidth = unit(6, "cm"), title.vjust = .75)) +
  labs(
    title = "24: Episode Ratings on trakt.tv",
    subtitle = "Episode ratings by trakt.tv users by season",
    x = "Episode Number", y = "Rating (1-10)", color = "# of Votes",
    caption = "jemus42.github.io/tRakt"
  ) +
  theme_minimal() +
  theme(
    legend.position = "bottom"
  )