Rationale

Agenda-setting theory says news coverage can shape what people view as important. Fox covered immigration more than CNN before the survey. If agenda‑setting holds, Fox viewers should be more likely to name immigration as the top issue.

Hypothesis

Variables & method

Results & discussion

Crosstab (counts with within-network percentages):

Crosstab: Preferred network × Immigration as top issue
Preferred network Top issue Not top issue Row total
Fox 115 (38.3%) 185 (61.7%) 300
CNN 35 (11.7%) 265 (88.3%) 300

Visualization:

Chi-square test:

Chi-square test of independence results
Statistic df p-value Cramer’s V N
56.889 1 0 0.308 600

Code (click to expand)

Show code
# Chart package
library(ggplot2)

# Load data (local file if present; otherwise download)
csv_path <- "TopIssue.csv"
if (!file.exists(csv_path)) {
  dat <- read.csv("https://drkblake.com/wp-content/uploads/2023/09/TopIssue.csv")
  write.csv(dat, csv_path, row.names = FALSE)
} else {
  dat <- read.csv(csv_path)
}

# Label factors
dat$PreferredNetwork <- factor(dat$PreferredNetwork, levels = c("Fox","CNN"))
dat$Immigration <- factor(dat$Immigration,
                          levels = c("1 Top issue","2 Not top issue"),
                          labels = c("Top issue","Not top issue"))

# Crosstab
tbl_counts <- table(dat$PreferredNetwork, dat$Immigration)     # rows: network; cols: issue
row_pct    <- prop.table(tbl_counts, 1)

# REQUIRED object: crosstab_table
crosstab_table <- data.frame(
  `Preferred network` = rownames(tbl_counts),
  `Top issue`         = sprintf("%d (%.1f%%)", tbl_counts[, "Top issue"],     100*row_pct[, "Top issue"]),
  `Not top issue`     = sprintf("%d (%.1f%%)", tbl_counts[, "Not top issue"], 100*row_pct[, "Not top issue"]),
  `Row total`         = rowSums(tbl_counts),
  check.names = FALSE, row.names = NULL
)

# REQUIRED object: graph
plot_df <- as.data.frame(tbl_counts)
names(plot_df) <- c("PreferredNetwork","Immigration","n")
denoms <- aggregate(n ~ PreferredNetwork, plot_df, sum)
names(denoms)[2] <- "total"
plot_df <- merge(plot_df, denoms, by = "PreferredNetwork")
plot_df$pct <- plot_df$n / plot_df$total

graph <- ggplot(plot_df, aes(x = PreferredNetwork, y = pct, fill = Immigration)) +
  geom_col() +
  scale_y_continuous(labels = function(x) paste0(round(x*100), "%")) +
  labs(title = "Share naming immigration as top issue by preferred network",
       x = "Preferred network", y = "Within-network percentage", fill = "Immigration") +
  theme_minimal(base_size = 12)

# Chi-square + effect size
chi <- suppressWarnings(chisq.test(tbl_counts, correct = FALSE))
N <- sum(tbl_counts)
cramers_v <- as.numeric(sqrt(chi$statistic / (N * (min(dim(tbl_counts)) - 1))))

# REQUIRED object: chitest_table
chitest_table <- data.frame(
  Statistic    = round(unname(chi$statistic), 3),
  df           = unname(chi$parameter),
  `p-value`    = signif(chi$p.value, 3),
  `Cramer's V` = round(cramers_v, 3),
  N            = N,
  check.names  = FALSE
)

# Helpers for text
fox_top <- row_pct["Fox","Top issue"]
cnn_top <- row_pct["CNN","Top issue"]
sig_text <- if (chi$p.value < .05) "There is an association (reject H0)." else "No evidence of an association (do not reject H0)."
direction <- if (fox_top > cnn_top) "Fox viewers report immigration as top issue more often than CNN viewers." else "CNN viewers report immigration as top issue more often than Fox viewers."