The agenda-setting theory predicts that issues that media content feature more prominently will become more prominent in the minds of their audience. This process is limited by the resources and space available for creating and publishing media content. As a result, media outlets must decide which issues to feature less to free up resources, time, and space for issues the media may consider to be more newsworthy. Therefore, issues will compete with one another for prominence on the media agenda. A media outlet may cover one issue extensively, which pushes another issue lower on the media agenda, or off the agenda entirely. However, at other times, these issues can trade places ,with one alternately higher and lower than the other on the media agenda. The two issues can also hold about the same consistency or importance on the media agenda.
Based on what first-level agenda-setting theory says about this phenomenon, my project will compare the media agenda prominence of two issues: climate change (climate crisis) and nonrenewable energy supply (energy crisis). Specifically, the analysis will compare the number of stories per week that MediaCloud.org’s United States - National News Archive collected about each crisis between the week starting on January 4, 2026 and the week ending on October 10, 2026.
The results will enhance the theoretical understanding of how similar-but-distinct issues, being two crisis’ in America, compete for attention on the media agenda.
Average weekly coverage volume of the crisis’s surrounding energy and climate differed during the first 10 months of 2026.
Weekly coverage volume of the two crisis’s served as the dependent variable for the analysis. It was measured continuously as the number of stories published per week that included terms a MediaCloud.org query specified as indicated coverage of one or the other.
The independent variable was “crisis,” measured categorically as either “Climate Crisis” or “Nonrenewable Energy Crisis” and operationalized as containing keywords likely to be unique to stories about one war or the other.
Stories about the Climate Crisis were operationalized as stories matching the MediaCloud query:
climate_query <-
"((climate change OR global warming OR extreme weather or emissions OR heat wave OR wildfire OR hurricane OR renewable energy))"
Meanwhile, stories about the Energy Crisis were operationalized as stories matching this MediaCloud query:
energy_query <-
"((crude oil OR gasoline prices OR opec OR oil refinery) AND (barrels OR supply OR drilling OR fuel OR petrol OR cost OR price))"
Eventually, I will use a paired-samples t-test to assess the statistical significance of coverage volume variation between the two story topics.
The figure and table below summarizes each crisis’s weekly coverage volume across the period analyzed. It appears that, for the months of March, April, and May of 2026, coverage volume of the energy crisis exceeded coverage volume of the climate crisis. The climate crisis’ average weekly coverage volume exceeded the average weekly coverage volume for the energy crisis. The same was true for the median coverage volume.
| topic | Total_Stories | Weekly_Minimum | Weekly_Maximum | Weekly_Median | Weekly_Mean | Weekly_SD |
|---|---|---|---|---|---|---|
| Climate Crisis | 3111 | 40 | 145 | 79 | 77.78 | 21.10 |
| Nonrenewable Energy Crisis | 2241 | 11 | 200 | 38 | 56.02 | 49.07 |
The likely explanation for the surge of coverage in the energy crisis is due to the Strait of Hormuz closing in March 2026. At this time, the climate crisis was still receiving about the same amount of coverage as it was on average.
Since the averages differ in the table, it seems likely that the data will support the hypothesis.
Here is the code used to produce the analysis.
############################################################
# STEP 1: Install and Load Required Packages
############################################################
required_packages <- c(
"tidyverse",
"httr2",
"lubridate",
"plotly",
"knitr",
"kableExtra"
)
for (pkg in required_packages) {
if (!requireNamespace(pkg, quietly = TRUE)) {
install.packages(pkg)
}
}
library(tidyverse)
library(httr2)
library(lubridate)
library(plotly)
library(knitr)
library(kableExtra)
############################################################
# STEP 2: Verify Media Cloud API Key
############################################################
if (!nzchar(Sys.getenv("MEDIACLOUD_KEY"))) {
stop(
"No Media Cloud API key was found.\n",
"Run the setup section once,\n",
"then restart R and try again."
)
}
mc_key <- Sys.getenv("MEDIACLOUD_KEY")
############################################################
# STEP 3: Define the Date Range
############################################################
start_date <- "2026-01-04"
end_date <- "2026-10-10"
############################################################
# STEP 4: Define Search Queries
############################################################
climate_query <-
"((climate change OR global warming OR extreme weather or emissions OR heat wave OR wildfire OR hurricane OR renewable energy))"
energy_query <-
"((crude oil OR gasoline prices OR opec OR oil refinery) AND (barrels OR supply OR drilling OR fuel OR petrol OR cost OR price))"
############################################################
# STEP 5: Create Topic Definitions
############################################################
topics <- c(
"Climate Crisis" = climate_query,
"Nonrenewable Energy Crisis" = energy_query
)
############################################################
# STEP 6: Create a Function to Retrieve Daily
# Story Counts
############################################################
mc_counts_over_time <- function(
query,
start_date,
end_date,
collection_id = 34412234
) {
resp <-
request(
"https://search.mediacloud.org/api/search/count-over-time"
) |>
req_headers(
Authorization = paste("Token", mc_key)
) |>
req_url_query(
q = query,
start = start_date,
end = end_date,
platform = "onlinenews-mediacloud",
cs = collection_id
) |>
req_perform()
results <- resp |>
resp_body_json()
map_dfr(
results$count_over_time$counts,
as_tibble
) |>
mutate(
date = as.Date(date)
)
}
############################################################
# STEP 7: Download Daily Counts for All Topics
############################################################
topic_data <-
imap_dfr(
topics,
function(search_string, topic_name) {
message(
"Downloading: ",
topic_name
)
results <-
mc_counts_over_time(
query = search_string,
start_date = start_date,
end_date = end_date
)
Sys.sleep(35)
results |>
mutate(
topic = topic_name
)
}
)
############################################################
# STEP 8: Examine the Downloaded Daily Data
############################################################
head(topic_data)
glimpse(topic_data)
############################################################
# STEP 9: Convert Daily Counts to Weekly Counts
############################################################
weekly_counts <-
topic_data |>
mutate(
week = floor_date(
date,
unit = "week"
)
) |>
group_by(
topic,
week
) |>
summarise(
stories = sum(count),
.groups = "drop"
)
############################################################
# STEP 10: Examine Weekly Counts
############################################################
weekly_counts
############################################################
# STEP 11: Summarize Coverage by Topic
############################################################
topic_summary <-
weekly_counts |>
group_by(topic) |>
summarise(
Total_Stories = sum(stories),
Weekly_Minimum = min(stories),
Weekly_Maximum = max(stories),
Weekly_Median = median(stories),
Weekly_Mean = round(
mean(stories),
2
),
Weekly_SD = round(
sd(stories),
2
),
.groups = "drop"
) |>
arrange(
desc(Total_Stories)
)
Table <-
topic_summary |>
kbl(
caption =
"Media Cloud Topic Summary Statistics",
align = "lrrrrrr"
) |>
kable_styling(
full_width = FALSE,
bootstrap_options = c(
"striped",
"hover",
"condensed"
)
)
Table
############################################################
# STEP 12: Create an Interactive Plotly Graph
############################################################
weekly_counts <- weekly_counts |>
mutate(
stories_formatted = formatC(
stories,
format = "d",
big.mark = ","
)
)
Graph <- plot_ly(
data = weekly_counts,
x = ~week,
y = ~stories,
color = ~topic,
colors = "Set1",
type = "scatter",
mode = "lines+markers",
customdata = ~topic,
text = ~stories_formatted,
hovertemplate =
paste(
"%{customdata}
",
"Week: %{x|%Y-%m-%d}
",
"Stories: %{text}
",
""
)
) |>
layout(
title =
"Weekly U.S. Coverage Volume",
hovermode = "x unified",
xaxis = list(
title = "Week"
),
yaxis = list(
title = "Weekly Story Count",
separatethousands = TRUE
)
)
Graph