Rationale

The nation is going through a tumultuous time in history, with the economy and immigration at a fever pitch. Right now, the government is shut down, and the economy has fluctuated throughout 2025. However, immigration has swelled with President Donald Trumps’ enforcement of undocumented Americans and their families. In Tennessee, this issue peaked when ICE partnered with the Tennessee Highway Patrol for traffic stops in south Nashville. Hundreds of people were arrested, and they were sent to detention facilities in New Orleans, Louisisana.

This scene has happened elsewhere across the country, these policy changes have led to protests, and it’s even affected the workforce.

The Associated Press has tracked these stories.

Hypothesis

Because of the tipping point of immigration in this country, I hypothesize that immigration and ICE will outweigh the coverage of the economy, even though these issues can be intrinsically linked. Undocumented people make up a bedrock of the economy in agriculture and other sectors.

Variables & method

An analysis of nearly 75,000 AP stories came into play. I wanted to know though how many stories the Associated Press had on the economy and immigration. That is where first-level agenda setting theory came into the picture. I used coding in R to delineate how many of those stories involved those issues. I looked at 42 weeks out of the year, which is through the end of September.

Descriptive Statistics: Pair Differences
count mean sd min max
40.000 9.450 18.506 −16.000 83.000
Normality Test (Shapiro-Wilk)
statistic p.value method
0.8768 0.0004 Shapiro-Wilk normality test
If the P.VALUE is 0.05 or less, the number of pairs is fewer than 40, and the distribution of pair differences shows obvious non-normality or outliers, consider using the Wilcoxon Signed Rank Test results instead of the Paired-Samples t-Test results.
Paired-Samples t-Test
statistic parameter p.value conf.low conf.high method
3.2297 39 0.0025 3.5316 15.3684 Paired t-test
Group Means and SDs (t-Test)
V1_Mean V2_Mean V1_SD V2_SD
25.625 35.075 9.478 16.004

Results and discussion

The comparison from the first-level agenda theory showed that dozens of stories appeared every week about both the economy and immigration, teeter tottering like on a see-saw.

That was until week 24, when immigration stories went off like a rocket launcher. That is where several top news issues happened:

This made for an incredibly busy news week. The stories slowly started trending down from the spike, and the issue of the economy never spiked as high as it did for issues with immigration.

Because of the nature of the news cycle, it seems the hypothesis was found to be accurate.

After doing a paired samples t-test, I came to learn that the means averaged out to be statistically signficant, meaning there were more stories about ICE than the economy.

# ============================================
# APNews text analysis (First-level agenda-setting theory version)
# ============================================

# ============================================
# --- Load required libraries ---
# ============================================

if (!require("tidyverse")) install.packages("tidyverse")
if (!require("tidytext")) install.packages("tidytext")

library(tidyverse)
library(tidytext)

# ============================================
# --- Load the APNews data ---
# ============================================

# Read the data from the web
FetchedData <- readRDS(url("https://github.com/drkblake/Data/raw/refs/heads/main/APNews.rds"))
# Save the data on your computer
saveRDS(FetchedData, file = "APNews.rds")
# remove the downloaded data from the environment
rm (FetchedData)

APNews <- readRDS("APNews.rds")

# ============================================
# --- Flag Topic1-related stories ---
# ============================================

# --- Define Topic1 phrases ---
phrases <- c(
  "ICE",
  "Immigration",
  "Undocumented",
  "southern border'",
  "deportation",
  "citizenship"
)

# --- Escape regex special characters ---
escaped_phrases <- str_replace_all(
  phrases,
  "([\\^$.|?*+()\\[\\]{}\\\\])",
  "\\\\\\1"
)

# --- Build whole-word/phrase regex pattern ---
pattern <- paste0("\\b", escaped_phrases, "\\b", collapse = "|")

# --- Apply matching to flag Topic1 stories ---
APNews <- APNews %>%
  mutate(
    Full.Text.clean = str_squish(Full.Text),  # normalize whitespace
    Topic1 = if_else(
      str_detect(Full.Text.clean, regex(pattern, ignore_case = TRUE)),
      "Yes",
      "No"
    )
  )

# ============================================
# --- Flag Topic2-related stories ---
# ============================================

# --- Define Topic2 phrases ---
phrases <- c(
  "economy",
  "economic",
  "workforce",
  "labor",
  "unemployment"
)

# --- Escape regex special characters ---
escaped_phrases <- str_replace_all(
  phrases,
  "([\\^$.|?*+()\\[\\]{}\\\\])",
  "\\\\\\1"
)

# --- Build whole-word/phrase regex pattern ---
pattern <- paste0("\\b", escaped_phrases, "\\b", collapse = "|")

# --- Apply matching to flag Topic2 stories ---
APNews <- APNews %>%
  mutate(
    Full.Text.clean = str_squish(Full.Text),
    Topic2 = if_else(
      str_detect(Full.Text.clean, regex(pattern, ignore_case = TRUE)),
      "Yes",
      "No"
    )
  )

# ============================================
# --- Visualize weekly counts of Topic1- and Topic2-related stories ---
# ============================================

# --- Load plotly if needed ---
if (!require("plotly")) install.packages("plotly")
library(plotly)

# --- Summarize weekly counts for Topic1 = "Yes" ---
Topic1_weekly <- APNews %>%
  filter(Topic1 == "Yes") %>%
  group_by(Week) %>%
  summarize(Count = n(), .groups = "drop") %>%
  mutate(Topic = "ICE") # Note custom Topic1 label

# --- Summarize weekly counts for Topic2 = "Yes" ---
Topic2_weekly <- APNews %>%
  filter(Topic2 == "Yes") %>%
  group_by(Week) %>%
  summarize(Count = n(), .groups = "drop") %>%
  mutate(Topic = "Economy") # Note custom Topic2 label

# --- Combine both summaries into one data frame ---
Weekly_counts <- bind_rows(Topic2_weekly, Topic1_weekly)

# --- Fill in missing combinations with zero counts ---
Weekly_counts <- Weekly_counts %>%
  tidyr::complete(
    Topic,
    Week = full_seq(range(Week), 1),  # generate all week numbers
    fill = list(Count = 0)
  ) %>%
  arrange(Topic, Week)

# --- Create interactive plotly line chart ---
AS1 <- plot_ly(
  data = Weekly_counts,
  x = ~Week,
  y = ~Count,
  color = ~Topic,
  colors = c("steelblue", "firebrick"),
  type = "scatter",
  mode = "lines+markers",
  line = list(width = 2),
  marker = list(size = 6)
) %>%
  layout(
    title = "Weekly Counts of Topic1- and Topic2-Related AP News Articles",
    xaxis = list(
      title = "Week Number (starting with Week 1 of 2025)",
      dtick = 1
    ),
    yaxis = list(title = "Number of Articles"),
    legend = list(title = list(text = "Topic")),
    hovermode = "x unified"
  )

# ============================================
# --- Show the chart ---
# ============================================

AS1