Packages

Below are the packages necessary for the analysis.

# Load all the necessary packages 
library(estimatr)
library(huxtable)
library(car)
library(broom.mixed)
library(modelsummary)
library(ggplot2)
library(gridExtra)
library(dplyr)
library(grid)
library(stargazer)
library(tidyverse)
library(rcartocolor)
library(cluster)
library(factoextra)
library(corrplot)
library(readr)
library(pheatmap)
library(writexl)
library(ggplot2)
library(jtools)
library(haven)
library(readr)
library(readxl)
library(hrbrthemes)
library(viridis)
library(igraph)
library(leaps)
library(lmtest)
library(fmsb)
library(RColorBrewer)
library(scales)
library(patchwork)
library(stargazer)

# Disable scientific notation
options(scipen=999)

Wave 1

# Load dataset for Wave 1
df1 <- read_csv("Data/Raw/AIgen_campaign_content_Wave1.csv")
## Rows: 1003 Columns: 379
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (19): StartDate, EndDate, IPAddress, RecordedDate, ResponseId, Distribu...
## dbl (345): Status, Progress, Duration__in_seconds_, Finished, LocationLatitu...
## lgl  (15): RecipientLastName, RecipientFirstName, RecipientEmail, ExternalRe...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Variable definition and recoding
df1 <- df1 %>%
  mutate(
    # keep as is
    tolerance_ai_campaign_content = max(Q28, na.rm=TRUE) - Q28,
    
    # recode prefer not to say as NA
    gender = ifelse(Q2 == 98, NA, Q2),
    
    # calculate age
    age = 2024 - Q3,
    
    # keep education as is
    education = Q5,
    
    # recode ethnic background into white dummy
    white = ifelse(Q7 == 1, 1, 0),
    
    # recode ideology
    ideology = ifelse(Q24 == 99, NA, Q24),
    
    # keep political interest as is
    political_interest = Q22,
    
    # keep Trump voter as is
    trump_voter = TrumpVoter,
    
    # keep AI use as is
    ai_use = Q26,
    
    # recode AI exposure
    ai_exposure_during_2024_campaign = ifelse(Q29 == 99, NA, Q29),
    
    # keep AI disorientation as is
    ability_recognize_ai = max(Q30, na.rm=TRUE) - Q30,
    
    # recode perceived exposure to disinfo
    perceived_exposure_disinfo = ifelse(Q13 == 99, NA, Q13),
    
    # keep disinfo disorientation as is
    ability_recognize_disinfo = max(Q14, na.rm=TRUE) - Q14,
    
    # keep distrust in media as is
    trust_in_media = max(Q15, na.rm=TRUE) - Q15,
    
    # keep election integrity confidence as is
    confidence_election_integrity = Q19
  )

Variables

  1. tolerance_ai_campaign_content: higher values mean greater tolerance

  2. education: level of education, where higher values mean more educated

  3. white: 1 = white; 0 = non-white

  4. ideology: measured on a scale from 0 to 10 where 0 means left, 10 means right, and 5 means center

  5. ai_use: greater values mean more frequent use, 0 = never, 4 = every day or almost every day

  6. ai_exposure_during_2024_campaign: greater values mean more frequent exposure, 0 = never, 4 = every day or almost every day

  7. ability_recognize_ai: ability to recognize AI content, greater values mean greater confidence

  8. perceived_exposure_disinfo: greater values mean greater exposure, 0 = never, 4 = every day or almost every day

  9. ability_recognize_disinfo: ability to recognize disinformation, greater values mean greater confidence trust_in_media: greater values mean greater trust in media

  10. confidence_election_integrity_bin: 0 = concerns about election integrity; 1 = confidence in election integrity

Correlation matrix

# creating a correlation matrix of significant variables

# 1) Select variables 
vars <- c(
  "tolerance_ai_campaign_content",
  "education",
  "white",
  "ideology",
  "ai_use",
  "ai_exposure_during_2024_campaign",
  "ability_recognize_ai",
  "perceived_exposure_disinfo",
  "ability_recognize_disinfo",
  "trust_in_media",
  "confidence_election_integrity",
  "political_interest",
  "trump_voter"
)

dat_num <- df1 %>%
  select(all_of(vars)) %>%
  mutate(across(everything(), ~ as.numeric(.)))

# 2) Correlation matrix (toggle method = "spearman" if you prefer rank correlations)
cor_mat <- cor(dat_num, use = "pairwise.complete.obs", method = "pearson")

# 3) P-value matrix helper
cor_pmat <- function(df) {
  m <- ncol(df)
  p.mat <- matrix(NA_real_, m, m)
  diag(p.mat) <- 0
  for (i in 1:(m - 1)) {
    for (j in (i + 1):m) {
      # use pairwise complete obs for each pair
      xy <- df[, c(i, j)]
      xy <- xy[complete.cases(xy), , drop = FALSE]
      if (nrow(xy) > 2) {
        p <- tryCatch(cor.test(xy[[1]], xy[[2]], method = "pearson")$p.value,
                      error = function(e) NA_real_)
      } else {
        p <- NA_real_
      }
      p.mat[i, j] <- p
      p.mat[j, i] <- p
    }
  }
  colnames(p.mat) <- colnames(df)
  rownames(p.mat) <- colnames(df)
  p.mat
}

p_mat <- cor_pmat(dat_num)

# 4) Optional: nicer labels for the plot
nice_labs <- c(
  tolerance_ai_campaign_content = "Tolerance toward AI content",
  education = "Education",
  white = "White",
  ideology = "Ideology",
  ai_use = "AI use",
  ai_exposure_during_2024_campaign = "AI exposure during 2024 campaign",
  ability_recognize_ai = "Ability to recognize AI content",
  perceived_exposure_disinfo = "Perceived exposure to disinfo",
  ability_recognize_disinfo = "Ability to recognize disinfo",
  trust_in_media = "Media trust",
  confidence_election_integrity = "Confidence in elections",
  political_interest = "Political interest",
  trump_voter = "Trump voter"
)

# Reorder via hierarchical clustering for clearer blocks
corrplot(
  cor_mat,
  method = "color",
  type = "upper",
  order = "hclust",
  tl.col = "black",
  tl.srt = 45,
  tl.cex = 0.8,
  tl.lab = nice_labs[colnames(cor_mat)],
  addCoef.col = "black",     # small coefficients on cells
  number.cex = 0.6,
  col = rcartocolor::carto_pal(11, "Sunset"),
  p.mat = p_mat,
  sig.level = 0.05,
  insig = "pch",
  diag = FALSE
)

# If you’d like a table of the correlations as well:
print(round(cor_mat, 2))

Regression wave 1

# Recode confidence into binary (0 = concerns, 1 = confidence)
df1 <- df1 %>%
  mutate(confidence_election_integrity_bin = ifelse(confidence_election_integrity == 2, 1,
                                             ifelse(confidence_election_integrity == 1, 0, NA)))

# Run OLS regression
model1 <- lm(
  tolerance_ai_campaign_content ~ education + white + ideology + 
    ai_use + ai_exposure_during_2024_campaign + ability_recognize_ai + 
    perceived_exposure_disinfo + ability_recognize_disinfo + 
    trust_in_media + confidence_election_integrity_bin + 
    political_interest + trump_voter, data=df1
)

# Format Regression Table
stargazer(model1, report = "vcsp*", type = "html", star.char = c(".", "*", "**", "***"), star.cutoffs = c(0.1, 0.05, 0.01, 0.001), notes = c(". p<0.1; * p<0.05; ** p<0.01; *** p<0.001"), notes.append = FALSE,  single.row=TRUE, dep.var.labels = c("Tolerance toward AI-generated campaign content"), title = "Regression Results (Wave 1)", covariate.labels = c("Education", "White", "Ideology", "Use of AI", "Exposure to AI content during campaign", "Ability to recognize AI content", "Perceived exposure to disinfo", "Ability to recognize disinfo", "Trust toward professional news media", "Confidence in election integrity", "Political interest", "Trump vote"))
Regression Results (Wave 1)
Dependent variable:
Tolerance toward AI-generated campaign content
Education 0.030 (0.038)
p = 0.425
White 0.201 (0.080)
p = 0.013*
Ideology -0.083 (0.014)
p = 0.000***
Use of AI -0.351 (0.035)
p = 0.000***
Exposure to AI content during campaign -0.066 (0.043)
p = 0.122
Ability to recognize AI content -0.318 (0.053)
p = 0.000***
Perceived exposure to disinfo -0.083 (0.040)
p = 0.041*
Ability to recognize disinfo 0.046 (0.104)
p = 0.662
Trust toward professional news media -0.221 (0.050)
p = 0.00002***
Confidence in election integrity -0.080 (0.083)
p = 0.338
Political interest -0.063 (0.049)
p = 0.198
Trump vote -0.001 (0.088)
p = 0.990
Constant 5.008 (0.261)
p = 0.000***
Observations 814
R2 0.344
Adjusted R2 0.334
Residual Std. Error 1.079 (df = 801)
F Statistic 34.981*** (df = 12; 801)
Note: . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Quick interpretation of results

  1. More conservative respondents are less tolerant of AI-generated campaign content.

  2. People who use AI more often are less tolerant of its use in campaigns. This is the strongest negative effect.

  3. Those who are better at spotting AI content are less tolerant of it in campaigns. Competence/literacy reduces tolerance, while inability to recognize AI content is associated with greater tolerance levels.

  4. Respondents who have more trust in the professional news media are less tolerant of AI-generated content in campaigns.

  5. White respondents are more tolerant of AI-generated campaign content than non-White respondents.

  6. People who feel more often exposed to disinformation are less tolerant of AI-generated content.

  7. non-significant predictors: education, exposure to AI content during camapign, ability to recognize disinformation, confidence in election integrity, political interest, trump vote

Wave 2

# Load dataset for Wave 2
df2 <- read_csv("Data/Raw/AIgen_campaign_content_Wave2.csv")
## Rows: 1059 Columns: 380
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (17): StartDate, EndDate, IPAddress, RecordedDate, ResponseId, Distribu...
## dbl (344): Status, Progress, Duration__in_seconds_, Finished, LocationLatitu...
## lgl  (19): RecipientLastName, RecipientFirstName, RecipientEmail, ExternalRe...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Variable definition and recoding
df2 <- df2 %>%
  mutate(
    # keep as is
    tolerance_ai_campaign_content = max(Q28, na.rm=TRUE) - Q28,
    
    # recode prefer not to say as NA
    gender = ifelse(Q2 == 98, NA, Q2),
    
    # calculate age
    age = 2024 - Q3,
    
    # keep education as is
    education = Q5,
    
    # recode ethnic background into white dummy
    white = ifelse(Q7 == 1, 1, 0),
    
    # recode ideology
    ideology = ifelse(Q24 == 99, NA, Q24),
    
    # keep political interest as is
    political_interest = Q22,
    
    # keep Trump voter as is
    trump_voter = TrumpVoter,
    
    # keep AI use as is
    ai_use = Q26,
    
    # recode AI exposure
    ai_exposure_during_2024_campaign = ifelse(Q29 == 99, NA, Q29),
    
    # keep AI disorientation as is
    ability_recognize_ai = max(Q30, na.rm=TRUE) - Q30,
    
    # recode perceived exposure to disinfo
    perceived_exposure_disinfo = ifelse(Q13 == 99, NA, Q13),
    
    # keep disinfo disorientation as is
    ability_recognize_disinfo = max(Q14, na.rm=TRUE) - Q14,
    
    # keep distrust in media as is
    trust_in_media = max(Q15, na.rm=TRUE) - Q15,
    
    # keep election integrity confidence as is
    confidence_election_integrity = Q19
  )
# creating a correlation matrix of significant variables

# 1) Select variables 
vars <- c(
  "tolerance_ai_campaign_content",
  "education",
  "white",
  "ideology",
  "ai_use",
  "ai_exposure_during_2024_campaign",
  "ability_recognize_ai",
  "perceived_exposure_disinfo",
  "ability_recognize_disinfo",
  "trust_in_media",
  "confidence_election_integrity",
  "political_interest",
  "trump_voter"
)

dat_num <- df2 %>%
  select(all_of(vars)) %>%
  mutate(across(everything(), ~ as.numeric(.)))

# 2) Correlation matrix (toggle method = "spearman" if you prefer rank correlations)
cor_mat <- cor(dat_num, use = "pairwise.complete.obs", method = "pearson")

# 3) P-value matrix helper
cor_pmat <- function(df) {
  m <- ncol(df)
  p.mat <- matrix(NA_real_, m, m)
  diag(p.mat) <- 0
  for (i in 1:(m - 1)) {
    for (j in (i + 1):m) {
      # use pairwise complete obs for each pair
      xy <- df[, c(i, j)]
      xy <- xy[complete.cases(xy), , drop = FALSE]
      if (nrow(xy) > 2) {
        p <- tryCatch(cor.test(xy[[1]], xy[[2]], method = "pearson")$p.value,
                      error = function(e) NA_real_)
      } else {
        p <- NA_real_
      }
      p.mat[i, j] <- p
      p.mat[j, i] <- p
    }
  }
  colnames(p.mat) <- colnames(df)
  rownames(p.mat) <- colnames(df)
  p.mat
}

p_mat <- cor_pmat(dat_num)

# 4) Optional: nicer labels for the plot
nice_labs <- c(
  tolerance_ai_campaign_content = "Tolerance toward AI content",
  education = "Education",
  white = "White",
  ideology = "Ideology",
  ai_use = "AI use",
  ai_exposure_during_2024_campaign = "AI exposure during 2024 campaign",
  ability_recognize_ai = "Ability to recognize AI content",
  perceived_exposure_disinfo = "Perceived exposure to disinfo",
  ability_recognize_disinfo = "Ability to recognize disinfo",
  trust_in_media = "Media trust",
  confidence_election_integrity = "Confidence in elections",
  political_interest = "Political interest",
  trump_voter = "Trump voter"
)

# Reorder via hierarchical clustering for clearer blocks
corrplot(
  cor_mat,
  method = "color",
  type = "upper",
  order = "hclust",
  tl.col = "black",
  tl.srt = 45,
  tl.cex = 0.8,
  tl.lab = nice_labs[colnames(cor_mat)],
  addCoef.col = "black",     # small coefficients on cells
  number.cex = 0.6,
  col = rcartocolor::carto_pal(11, "Sunset"),
  p.mat = p_mat,
  sig.level = 0.05,
  insig = "pch",
  diag = FALSE
)

# If you’d like a table of the correlations as well:
print(round(cor_mat, 2))

Regression wave 2

# Recode confidence into binary (0 = concerns, 1 = confidence)
df2 <- df2 %>%
  mutate(confidence_election_integrity_bin = ifelse(confidence_election_integrity == 2, 1,
                                             ifelse(confidence_election_integrity == 1, 0, NA)))

# Run OLS regression
model2 <- lm(
  tolerance_ai_campaign_content ~ education + white + ideology + 
    ai_use + ai_exposure_during_2024_campaign + ability_recognize_ai + 
    perceived_exposure_disinfo + ability_recognize_disinfo + 
    trust_in_media + confidence_election_integrity_bin + 
    political_interest + trump_voter, data=df2
)

# Format Regression Table
stargazer(model2, report = "vcsp*", type = "html", star.char = c(".", "*", "**", "***"), star.cutoffs = c(0.1, 0.05, 0.01, 0.001), notes = c(". p<0.1; * p<0.05; ** p<0.01; *** p<0.001"), notes.append = FALSE,  single.row=TRUE, dep.var.labels = c("Tolerance toward AI-generated campaign content"), title = "Regression Results (Wave 2)", covariate.labels = c("Education", "White", "Ideology", "Use of AI", "Exposure to AI content during campaign", "Ability to recognize AI content", "Perceived exposure to disinfo", "Ability to recognize disinfo", "Trust toward professional news media", "Confidence in election integrity", "Political interest", "Trump vote"))
Regression Results (Wave 2)
Dependent variable:
Tolerance toward AI-generated campaign content
Education -0.024 (0.038)
p = 0.530
White 0.297 (0.078)
p = 0.0002***
Ideology -0.050 (0.015)
p = 0.001***
Use of AI -0.437 (0.034)
p = 0.000***
Exposure to AI content during campaign -0.065 (0.038)
p = 0.087.
Ability to recognize AI content -0.167 (0.053)
p = 0.002**
Perceived exposure to disinfo -0.048 (0.038)
p = 0.214
Ability to recognize disinfo -0.102 (0.103)
p = 0.325
Trust toward professional news media -0.368 (0.048)
p = 0.000***
Confidence in election integrity -0.036 (0.092)
p = 0.697
Political interest -0.004 (0.048)
p = 0.940
Trump vote -0.096 (0.088)
p = 0.271
Constant 5.009 (0.257)
p = 0.000***
Observations 802
R2 0.388
Adjusted R2 0.379
Residual Std. Error 1.052 (df = 789)
F Statistic 41.663*** (df = 12; 789)
Note: . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Quick interpretation of results

  1. More conservative respondents are still less tolerant of AI-generated campaign content.

  2. Frequent AI users remain less tolerant. The effect is stronger in wave 2.

  3. People who trust mainstream media are less tolerant of AI in campaigns. The effect is stronger in wave 2.

  4. White respondents are more tolerant than non-White respondents. The effect is stronger in wave 2. Respondents who are confident in their ability to recognize AI content remain less tolerant of it, though the effect is weaker in wave 2.

  5. Perceived exposure to disinformation is non-significant for wave 2.

  6. Non-significant for both waves: education, ability to recognize disinformation, confidence in election integrity, political interest, and trump vote.,

  7. R² improves from 0.34 (Wave 1) to 0.39 (Wave 2). Predictors explain more variance in tolerance in Wave 2.

  8. The F-statistic also increases, reinforcing that the Wave 2 model fits slightly better.

Wave 3

# Load dataset for Wave 3
df3 <- read_csv("Data/Raw/AIgen_campaign_content_Wave3.csv")
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
## Rows: 1099 Columns: 397
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr   (30): StartDate, EndDate, IPAddress, RecordedDate, ResponseId, Distrib...
## dbl  (351): Status, Progress, Duration__in_seconds_, Finished, RecipientLast...
## lgl   (15): Q44, tg, survey_id, Q_BallotBoxStuffing, Q_RelevantIDDuplicate, ...
## dttm   (1): Q_Quality_TIMESTAMP
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Variable definition and recoding
df3 <- df3 %>%
  mutate(
    # keep as is
    tolerance_ai_campaign_content = max(Q28, na.rm=TRUE) - Q28,
    
    # recode prefer not to say as NA
    gender = ifelse(Q2 == 98, NA, Q2),
    
    # calculate age
    age = 2024 - Q3,
    
    # keep education as is
    education = Q5,
    
    # recode ethnic background into white dummy
    white = ifelse(Q7 == 1, 1, 0),
    
    # recode ideology
    ideology = ifelse(Q24 == 99, NA, Q24),
    
    # keep political interest as is
    political_interest = Q22,
    
    # keep Trump voter as is
    trump_voter = TrumpVoter,
    
    # keep AI use as is
    ai_use = Q26,
    
    # recode AI exposure
    ai_exposure_during_2024_campaign = ifelse(Q29 == 99, NA, Q29),
    
    # keep AI disorientation as is
    ability_recognize_ai = max(Q30, na.rm=TRUE) - Q30,
    
    # recode perceived exposure to disinfo
    perceived_exposure_disinfo = ifelse(Q13 == 99, NA, Q13),
    
    # keep disinfo disorientation as is
    ability_recognize_disinfo = max(Q14, na.rm=TRUE) - Q14,
    
    # keep distrust in media as is
    trust_in_media = max(Q15, na.rm=TRUE) - Q15,
    
    # keep election integrity confidence as is
    confidence_election_integrity = Q19
  )
# creating a correlation matrix of significant variables

# 1) Select variables 
vars <- c(
  "tolerance_ai_campaign_content",
  "education",
  "white",
  "ideology",
  "ai_use",
  "ai_exposure_during_2024_campaign",
  "ability_recognize_ai",
  "perceived_exposure_disinfo",
  "ability_recognize_disinfo",
  "trust_in_media",
  "confidence_election_integrity",
  "political_interest",
  "trump_voter"
)

dat_num <- df3 %>%
  select(all_of(vars)) %>%
  mutate(across(everything(), ~ as.numeric(.)))

# 2) Correlation matrix (toggle method = "spearman" if you prefer rank correlations)
cor_mat <- cor(dat_num, use = "pairwise.complete.obs", method = "pearson")

# 3) P-value matrix helper
cor_pmat <- function(df) {
  m <- ncol(df)
  p.mat <- matrix(NA_real_, m, m)
  diag(p.mat) <- 0
  for (i in 1:(m - 1)) {
    for (j in (i + 1):m) {
      # use pairwise complete obs for each pair
      xy <- df[, c(i, j)]
      xy <- xy[complete.cases(xy), , drop = FALSE]
      if (nrow(xy) > 2) {
        p <- tryCatch(cor.test(xy[[1]], xy[[2]], method = "pearson")$p.value,
                      error = function(e) NA_real_)
      } else {
        p <- NA_real_
      }
      p.mat[i, j] <- p
      p.mat[j, i] <- p
    }
  }
  colnames(p.mat) <- colnames(df)
  rownames(p.mat) <- colnames(df)
  p.mat
}

p_mat <- cor_pmat(dat_num)

# 4) Optional: nicer labels for the plot
nice_labs <- c(
  tolerance_ai_campaign_content = "Tolerance toward AI content",
  education = "Education",
  white = "White",
  ideology = "Ideology",
  ai_use = "AI use",
  ai_exposure_during_2024_campaign = "AI exposure during 2024 campaign",
  ability_recognize_ai = "Ability to recognize AI content",
  perceived_exposure_disinfo = "Perceived exposure to disinfo",
  ability_recognize_disinfo = "Ability to recognize disinfo",
  trust_in_media = "Media trust",
  confidence_election_integrity = "Confidence in elections",
  political_interest = "Political interest",
  trump_voter = "Trump voter"
)

# Reorder via hierarchical clustering for clearer blocks
corrplot(
  cor_mat,
  method = "color",
  type = "upper",
  order = "hclust",
  tl.col = "black",
  tl.srt = 45,
  tl.cex = 0.8,
  tl.lab = nice_labs[colnames(cor_mat)],
  addCoef.col = "black",     # small coefficients on cells
  number.cex = 0.6,
  col = rcartocolor::carto_pal(11, "Sunset"),
  p.mat = p_mat,
  sig.level = 0.05,
  insig = "pch",
  diag = FALSE
)

# If you’d like a table of the correlations as well:
print(round(cor_mat, 2))

Regression wave 2

# Recode confidence into binary (0 = concerns, 1 = confidence)
df3 <- df3 %>%
  mutate(confidence_election_integrity_bin = ifelse(confidence_election_integrity == 2, 1,
                                             ifelse(confidence_election_integrity == 1, 0, NA)))

# Run OLS regression
model3 <- lm(
  tolerance_ai_campaign_content ~ education + white + ideology + 
    ai_use + ai_exposure_during_2024_campaign + ability_recognize_ai + 
    perceived_exposure_disinfo + ability_recognize_disinfo + 
    trust_in_media + confidence_election_integrity_bin + 
    political_interest + trump_voter, data=df3
)

# Format Regression Table
stargazer(model3, report = "vcsp*", type = "html", star.char = c(".", "*", "**", "***"), star.cutoffs = c(0.1, 0.05, 0.01, 0.001), notes = c(". p<0.1; * p<0.05; ** p<0.01; *** p<0.001"), notes.append = FALSE,  single.row=TRUE, dep.var.labels = c("Tolerance toward AI-generated campaign content"), title = "Regression Results (Wave 3)", covariate.labels = c("Education", "White", "Ideology", "Use of AI", "Exposure to AI content during campaign", "Ability to recognize AI content", "Perceived exposure to disinfo", "Ability to recognize disinfo", "Trust toward professional news media", "Confidence in election integrity", "Political interest", "Trump vote"))
Regression Results (Wave 3)
Dependent variable:
Tolerance toward AI-generated campaign content
Education -0.039 (0.040)
p = 0.328
White 0.172 (0.081)
p = 0.036*
Ideology -0.062 (0.015)
p = 0.0001***
Use of AI -0.411 (0.033)
p = 0.000***
Exposure to AI content during campaign -0.038 (0.040)
p = 0.338
Ability to recognize AI content -0.150 (0.052)
p = 0.005**
Perceived exposure to disinfo -0.116 (0.038)
p = 0.003**
Ability to recognize disinfo -0.007 (0.105)
p = 0.945
Trust toward professional news media -0.298 (0.051)
p = 0.000***
Confidence in election integrity 0.214 (0.090)
p = 0.019*
Political interest -0.173 (0.050)
p = 0.001***
Trump vote -0.277 (0.093)
p = 0.003**
Constant 5.431 (0.259)
p = 0.000***
Observations 798
R2 0.413
Adjusted R2 0.404
Residual Std. Error 1.075 (df = 785)
F Statistic 46.094*** (df = 12; 785)
Note: . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Quick interpretation of results

  1. More conservative respondents are still less tolerant of AI in campaigns.

  2. Frequent AI users are still less tolerant of AI generated content in political campaigns. The effect is very strong and stable across waves.

  3. People who trust professional media are less tolerant of campaigns using AI-generated content. This relationship is robust across all three waves.

  4. The ability to recognize AI still predicts discomfort with AI generated campaign content.

  5. White respondents remain more tolerant, though the effect is smaller than wave 2.

  6. Tolerance for AI-generated content in political campaigns decreases for those who feel heavily exposed to disinformation. This effect was present in wave 1, faded in wave 2, and reappears here in wave 3.

  7. Confidence in the integrity of the 2024 election, which was not significant during wave 1 and 2, is now significant. Those confident in the outcome of the election are more tolerant of campaigns using AI to generate content.

  8. Another, new effect concerns political interest. More politically interested respondents are less tolerant of AI-generated content.

  9. Trump voters are less tolerant even controlling for ideology. This is also a new effect that was not present during waves 1 and 2.

  10. Remain non-significant: education, exposure to Ai during the campaign, and perceived ability to recognize disinformation.

  11. R² = 0.413 (Adj. R² = 0.404). That’s the best model of the three, explaining over 40% of the variance. The F-statistic is higher too.

Cross-wave comparison

stargazer(
  model1, model2, model3,
  type = "html",
  title = "Regression Results Across Waves",
  dep.var.labels = c("Tolerance toward AI-generated campaign content"),
  column.labels = c("Wave 1", "Wave 2", "Wave 3"),
  covariate.labels = c(
    "Education", 
    "White", 
    "Ideology", 
    "Use of AI", 
    "Exposure to AI content during campaign", 
    "Ability to recognize AI content", 
    "Perceived exposure to disinfo", 
    "Ability to recognize disinfo", 
    "Trust toward professional news media", 
    "Confidence in election integrity", 
    "Political interest", 
    "Trump vote"
  ),
  star.char = c(".", "*", "**", "***"),
  star.cutoffs = c(0.1, 0.05, 0.01, 0.001),
  notes = c(". p<0.1; * p<0.05; ** p<0.01; *** p<0.001"),
  notes.append = FALSE,
  single.row = TRUE
)
Regression Results Across Waves
Dependent variable:
Tolerance toward AI-generated campaign content
Wave 1 Wave 2 Wave 3
(1) (2) (3)
Education 0.030 (0.038) -0.024 (0.038) -0.039 (0.040)
White 0.201* (0.080) 0.297*** (0.078) 0.172* (0.081)
Ideology -0.083*** (0.014) -0.050*** (0.015) -0.062*** (0.015)
Use of AI -0.351*** (0.035) -0.437*** (0.034) -0.411*** (0.033)
Exposure to AI content during campaign -0.066 (0.043) -0.065. (0.038) -0.038 (0.040)
Ability to recognize AI content -0.318*** (0.053) -0.167** (0.053) -0.150** (0.052)
Perceived exposure to disinfo -0.083* (0.040) -0.048 (0.038) -0.116** (0.038)
Ability to recognize disinfo 0.046 (0.104) -0.102 (0.103) -0.007 (0.105)
Trust toward professional news media -0.221*** (0.050) -0.368*** (0.048) -0.298*** (0.051)
Confidence in election integrity -0.080 (0.083) -0.036 (0.092) 0.214* (0.090)
Political interest -0.063 (0.049) -0.004 (0.048) -0.173*** (0.050)
Trump vote -0.001 (0.088) -0.096 (0.088) -0.277** (0.093)
Constant 5.008*** (0.261) 5.009*** (0.257) 5.431*** (0.259)
Observations 814 802 798
R2 0.344 0.388 0.413
Adjusted R2 0.334 0.379 0.404
Residual Std. Error 1.079 (df = 801) 1.052 (df = 789) 1.075 (df = 785)
F Statistic 34.981*** (df = 12; 801) 41.663*** (df = 12; 789) 46.094*** (df = 12; 785)
Note: . p<0.1; * p<0.05; ** p<0.01; *** p<0.001
# Plot models with clean labels
coef_labels <- c(
  "Education"                              = "education",
  "White"                                  = "white",
  "Ideology"                               = "ideology",
  "Personal use of AI"                              = "ai_use",
  "Exposure to AI-content during 2024 campaign"       = "ai_exposure_during_2024_campaign",
  "Perceived ability to recognize AI content"        = "ability_recognize_ai",
  "Perceived exposure to disinfo"          = "perceived_exposure_disinfo",
  "Perceived ability to recognize disinfo"           = "ability_recognize_disinfo",
  "Trust in news media"                            = "trust_in_media",
  "Confidence in election integrity"                = "confidence_election_integrity_bin",
  "Political interest"                     = "political_interest",
  "Vote for Trump"                             = "trump_voter"
)

p_overlay <- plot_summs(
  model1, model2, model3,
  model.names = c("Wave 1", "Wave 2", "Wave 3"),
  coefs       = coef_labels,  # apply labels + order
  scale       = TRUE,         # standardized coefficients
  robust      = "HC2",        # robust CIs
  ci.level    = 0.95,
  plot.distributions = FALSE,
  exclude.intercept = TRUE,
  point.size  = 2.6,
  line.size   = 0.7,
  colors      = c("darkgoldenrod1", "coral", "brown")  # calm, high-contrast palette
) +
  geom_vline(xintercept = 0, linetype = 2, linewidth = 0.5) +
  labs(x = "Standardized coefficient (β)", y = NULL, title = NULL) +
  theme_minimal(base_size = 12) +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    panel.grid.minor = element_blank(),
    axis.text.y = element_text(size = 10)
  )

p_overlay