How we’re feeling, over time

This analysis was made possible by the mdr R package, which used data originally compiled by the Severance wiki. Here, we create a little sentiment profile for each episode, binning them in three minute increments and calculating the AFINN average sentiment score in each.

Code
library(tidytext)
library(mdr)
library(tidyverse)

df <- transcripts |>
  mutate(timestamp_seconds = as.numeric(timestamp), 
         bin = floor(timestamp_seconds / 180) * 180) |>
  left_join(episodes, by = c("season", "episode"))

df |>
  mutate(id = glue::glue("Season {season} Episode {episode}\nWritten by: {writer}")) |>
  unnest_tokens(word, dialogue) |>
  inner_join(get_sentiments("afinn"), by = "word") |>
  group_by(id, bin) |>
  summarise(sentiment = mean(value)) |>
  ggplot(aes(x = bin, y = sentiment, fill = sentiment > 0)) + 
  geom_bar(stat = "identity", alpha = 0.8) +
  scale_fill_manual(values = c("#C15C58", "#5BA9D0")) +
  scale_x_time(labels = scales::time_format("%M:%S")) +
  labs(x = "") +
  facet_wrap(~id) + 
  theme_mdr() + 
  theme(
    axis.title = element_text(color = "black"),
    axis.text = element_text(color = "black"),
    plot.background = element_rect(fill = "#CFE0E1"),
    panel.background = element_rect(fill = "white"),
    legend.position = "none",
    panel.grid.minor = element_blank())