This analysis compares media coverage of AI-related job losses with coverage of AI-related jobs. The Media Cloud data show weekly story counts from January 1, 2025, through September 4, 2026.
The most noticeable spike occurs in October 2025, when coverage of AI-related jobs rose sharply compared with coverage of AI job losses.
Data source: Media Cloud
The top-source distribution differs noticeably between the two searches, with AI jobs coverage more concentrated in Forbes and AI job-loss coverage distributed more evenly across several outlets.
| AI Jobs Source | % | AI Job Losses Source | % |
|---|---|---|---|
| Forbes | 23.970% | Breitbart | 9.756% |
| Business Insider | 9.434% | Fortune | 9.756% |
| Fortune | 9.101% | Forbes | 9.451% |
| Benzinga | 8.990% | ZDNET | 8.537% |
| CNBC | 5.549% | Benzinga | 6.707% |
| TechRadar | 3.219% | The Week | 6.402% |
| Inquirer | 2.664% | Business Insider | 5.488% |
| Investors.com | 2.109% | CNBC | 3.049% |
| ZDNET | 1.998% | Investors.com | 3.049% |
| International Business Times | 1.665% | TechRadar | 2.744% |
Here is the R code that was used to create this graph
############################################################
# 1. Load required packages and Media Cloud data
############################################################
library(tidyverse)
library(plotly)
AI_jobs <- read_csv("AI_jobs.csv")
AI_job_losses <- read_csv("AI_job_losses.csv")
############################################################
# 2. Combine the two Media Cloud datasets
############################################################
MediaCloudLong <- bind_rows(
AI_jobs %>% mutate(Topic = "AI Jobs"),
AI_job_losses %>% mutate(Topic = "AI Job Losses")
)
############################################################
# 3. Convert dates and create Monday-based weeks
############################################################
MediaCloudLong <- MediaCloudLong %>%
mutate(
date = as.Date(date),
Week = as.Date(
cut(
date,
breaks = "week",
start.on.monday = TRUE
)
)
)
############################################################
# 4. Aggregate daily story counts into weekly totals
############################################################
MediaCloudWeekly <- MediaCloudLong %>%
group_by(Week, Topic) %>%
summarize(
Stories = sum(count),
.groups = "drop"
)
############################################################
# 5. Remove partial beginning and ending weeks
############################################################
MediaCloudWeekly <- MediaCloudWeekly %>%
filter(
Week > min(Week),
Week < max(Week)
)
############################################################
# 6. Create tooltip information
############################################################
MediaCloudWeekly <- MediaCloudWeekly %>%
mutate(
Tooltip = paste0(
"Topic: ", Topic,
"<br>Week Beginning: ", format(Week, "%Y-%m-%d"),
"<br>Stories: ", Stories
)
)
############################################################
# 7. Create interactive Plotly line chart
############################################################
Plot <- plot_ly(
data = MediaCloudWeekly,
x = ~Week,
y = ~Stories,
color = ~Topic,
colors = c(
"AI Job Losses" = "black",
"AI Jobs" = "#6B8E5A"
),
type = "scatter",
mode = "lines+markers",
text = ~Tooltip,
hoverinfo = "text"
) %>%
layout(
title = "Weekly Media Coverage: AI Jobs vs. AI Job Losses",
xaxis = list(
title = "Week Beginning"
),
yaxis = list(
title = "Story Count"
),
legend = list(
title = list(
text = "Topic"
)
),
annotations = list(
list(
x = as.Date("2025-10-20"),
y = 51,
text = "October 2025 spike<br>51 AI Jobs stories",
showarrow = TRUE,
arrowhead = 2,
ax = 70,
ay = -50
)
)
)
############################################################
# 8. Display chart
############################################################
Plot