```{r, include=FALSE} ############################################################ # 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.”, “Run the setup section once,”, “then restart R and try again.” ) }

mc_key <- Sys.getenv(“MEDIACLOUD_KEY”)

STEP 3: Define the Date Range

start_date <- “2025-01-01” end_date <- “2026-01-01”

STEP 4: Define Search Queries

nfl_query <- “(nfl OR national football league)”

cfb_query <- “(fbs college football OR college football)”

STEP 5: Create Topic Definitions

topics <- c( “NFL” = nfl_query, “College Football” = cfb_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


## **Rationale**

First-level agenda-setting theory suggests that the more attention the media gives to a topic, the more important that topic may seem to the public. For example, when news outlets frequently cover a certain sport, audiences may be more likely to see that sport as important or relevant.

Considering this, my project will compare news coverage of the NFL and college football to see which receives more attention from U.S. news media. Using Media Cloud data, I will compare the number of stories published about each topic per week from 01/01/2025, through 01/01/2026.

## **Hypothesis**

U.S. news media will give significantly more weekly coverage to the College Football than to the NFL during 2025.

## **Variables & method**

The dependent variable is weekly news coverage, measured by the number of stories published about each football level each week. The independent variable is the football level, either the NFL or college football.

Stories about the NFL were operationalized as stories matching the MediaCloud query:

nfl_query \<- "(nfl OR national football league)"

Stories about College Football were operationalized as stories matching the MediaCloud query:

cfb_query \<- "(fbs college football OR college football)"

Using Media Cloud's United States - National news archive to compare coverage of both topics from January 1, 2025, through January 1, 2026.

## **Results & discussion**

The graph and table below compare weekly news coverage of the NFL and college football. The results show which topic received more media attention and whether College Football received more coverage on average.

```{r},echo=FALSE}
Plot

The graph shows that the NFL recceives substantialy more coverage than College Football, one reason fot his could be the overwhelming national attention that the NFL gets, as well as the increased attention drawn to it because of gambling and sports betting apps. I thought that College Football would have more coverage because there are more teams and more games, so I thought that would mean there would be more to cover.

Code:

```{r},eval=FALSE} ############################################################ # 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.”, “Run the setup section once,”, “then restart R and try again.” ) }

mc_key <- Sys.getenv(“MEDIACLOUD_KEY”)

STEP 3: Define the Date Range

start_date <- “2025-01-01” end_date <- “2026-01-01”

STEP 4: Define Search Queries

nfl_query <- “(nfl OR national football league)”

cfb_query <- “(fbs college football OR college football)”

STEP 5: Create Topic Definitions

topics <- c( “NFL” = nfl_query, “College Football” = cfb_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

```