This data on the graph shows that Artificial Intelligence was a much more popular topic to cover media members over the past year. AI led the entire way and reached its peak on May 10th with 2,342 stories. The peak for Climate Change was May 3, 2026 with 1,128 storie total and reached its nadir on September 6th with just 651 stories. The low point for Artificial Intelligence was March 29th with 1,246 stories.
Code
Here is the code below that I used for this graph development.
############################################################
# STEP 1: Install and Load Packages
############################################################
if (!require("tidyverse")) install.packages("tidyverse")
if (!require("httr2")) install.packages("httr2")
if (!require("lubridate")) install.packages("lubridate")
if (!require("kableExtra")) install.packages("kableExtra")
library(tidyverse)
library(httr2)
library(lubridate)
library(kableExtra)
############################################################
# STEP 2: Verify Media Cloud API Key
############################################################
if (!nzchar(Sys.getenv("MEDIACLOUD_KEY"))) {
stop(
"No Media Cloud API key was found.\n",
"Please save your key to .Renviron first."
)
}
############################################################
# STEP 3: Define Two Topics
############################################################
# Replace the topic labels and search queries below.
#
# Examples:
# "artificial intelligence"
# "climate change"
# "immigration"
# "inflation"
topics <- c(
"Artificial Intelligence" = "\"artificial intelligence\"",
"Climate Change" = "\"climate change\""
)
############################################################
# STEP 4: Define the Date Range
############################################################
start_date <- "2026-01-11"
end_date <- "2026-09-12"
############################################################
# STEP 5: Create a Function to Download
# Daily Story Counts.
############################################################
get_counts <- function(query) {
Sys.sleep(35)
response <-
request(
"https://search.mediacloud.org/api/search/count-over-time"
) |>
req_headers(
Authorization = paste(
"Token",
Sys.getenv("MEDIACLOUD_KEY")
)
) |>
req_url_query(
q = query,
start = start_date,
end = end_date,
platform = "onlinenews-mediacloud",
cs = 34412234
) |>
req_perform()
results <-
response |>
resp_body_json()
map_dfr(
results$count_over_time$counts,
as_tibble
) |>
mutate(
date = as.Date(date)
)
}
############################################################
# STEP 6: Download Data for Both Topics
############################################################
topic_data <-
imap_dfr(
topics,
function(search_query, topic_name) {
message("Downloading: ", topic_name)
get_counts(search_query) |>
mutate(
topic = topic_name
)
}
)
############################################################
# STEP 7: Examine the Downloaded Data
############################################################
head(topic_data)
glimpse(topic_data)
############################################################
# STEP 8: Calculate Weekly Story Counts
############################################################
weekly_counts <-
topic_data |>
mutate(
week = floor_date(date, unit = "week")
) |>
group_by(topic, week) |>
summarise(
stories = sum(count),
.groups = "drop"
)
############################################################
# STEP 9: Display Weekly Counts
############################################################
weekly_counts |>
arrange(topic, week) |>
kbl(
caption = "Weekly Media Cloud Story Counts"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c(
"striped",
"hover"
)
)
############################################################
# STEP 10: Summarize Total Coverage
############################################################
topic_summary <-
weekly_counts |>
group_by(topic) |>
summarise(
Total_Stories = sum(stories),
Weekly_Minimum = min(stories),
Weekly_Maximum = max(stories),
Weekly_Mean = round(mean(stories), 2),
.groups = "drop"
) |>
arrange(desc(Total_Stories))
Summary_Table <- topic_summary |>
kbl(
caption = "Coverage Summary by Topic"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c(
"striped",
"hover"
)
)
Summary_Table
############################################################
# STEP 11: Create a Line Graph
############################################################
Line_Graph <- weekly_counts |>
ggplot(
aes(
x = week,
y = stories,
color = topic
)
) +
geom_line(
linewidth = 1
) +
geom_point(
size = 2
) +
labs(
title = "Weekly Media Coverage Volume",
subtitle = "Comparison of Two Topics",
x = "Week",
y = "Number of Stories",
color = "Topic"
) +
theme_minimal()
Line_Graph
if (!require("plotly")) install.packages("plotly")
if (!require("RColorBrewer")) install.packages("RColorBrewer")
library(plotly)
library(RColorBrewer)
Plotly_Line_Graph <- plot_ly(
data = weekly_counts,
x = ~week,
y = ~stories,
color = ~topic,
colors = brewer.pal(9, "Set1"),
type = "scatter",
mode = "lines+markers",
hovertemplate = paste(
"<b>%{fullData.name}</b><br>",
"Stories: %{y:,}<extra></extra>"
)
) |>
plotly::layout(
title = "Weekly Media Coverage Volume",
hovermode = "x unified",
xaxis = list(
title = "Week"
),
yaxis = list(
title = "Number of Stories",
tickformat = ",d"
),
legend = list(
title = list(text = "Topic")
)
)
Plotly_Line_Graph
############################################################
# STEP 12: Save Results as a CSV File
############################################################
write_csv(
weekly_counts,
"weekly_story_counts.csv"
)