Packages Needed

pkgs <- c(
  "broom","broom.mixed","car","cluster","corrplot","dplyr","estimatr","factoextra",
  "fmsb","ggforce","ggplot2","grid","gridExtra","haven","huxtable","igraph",
  "jtools","knitr","leaps","lmtest","modelsummary","patchwork","pheatmap","psych",
  "rcartocolor","readr","readxl","relimpo","RColorBrewer","sandwich","scales",
  "stargazer","tibble","tidyr","tidyverse","viridis","writexl"
)
invisible(lapply(pkgs, require, character.only = TRUE))

# Disable scientific notation
options(scipen=999)

Data Pre-Processing

# Load dataset
df1 <- read_csv("Data/Raw/DemocracySurvey_Wave2.csv")


# Variable definition and recoding
df1 <- df1 %>%
  mutate(
    # Acceptance of Trump lawbreaking: keep as is
    trump_lawbreaking_acceptance =  Q39,
    
    # Support for Trump emergency powers: keep as is
    trump_emergency_powers_support =  Q40,
    
    # Gender: recode "prefer not to say" as NA
    gender = ifelse(Q2 == 98, NA, Q2),
    
    # Age: calculate from birth year
    age = 2024 - Q3,
    
    # Education: keep as is
    education = Q5,
    
    # Republican: keep as is
    republican = Republicans,
    
    # White: recode ethnic background (Q7) into white dummy
    white = ifelse(Q7 == 1, 1, 0),
    
    # Ideology: recode DKs as NA
    ideology = ifelse(Q24 == 99, NA, Q24),
    
    # Political interest: keep as is
    political_interest = Q22,
    
    # Trump voter: keep as is
    trump_voter = TrumpVoter,
    
    # Feelings of Being Devalued: compute index scores from Q20 
    fbd = rowMeans(across(c(Q20_1, Q20_2, Q20_3)), na.rm = TRUE),
    
    # Machiavellianism: compute index scores from Q33
    machiavellianism = rowMeans(across(all_of(paste0("Q33_", 1:7))), na.rm = TRUE),
    
    # Narcissism: compute index scores from Q34
    narcissism      = rowMeans(across(all_of(paste0("Q34_", 1:7))), na.rm = TRUE),
    
    # Psychopathy: compute index scores from Q34
    psychopathy     = rowMeans(across(all_of(paste0("Q35_", 1:7))), na.rm = TRUE),
   
    # Social Dominance Orientation: 
    ## First, reverse-code items:
    Q16_3r = 8 - Q16__3,
    Q16_4r = 8 - Q16__4,
    Q16_7r = 8 - Q16__7,
    Q16_8r = 8 - Q16__8,
    
    ## Second, compute index scores from Q16 after reversing the 4 items
    sdo = rowMeans(across(c(Q16__1, Q16__2, Q16_3r, Q16_4r, Q16__5, Q16__6, Q16_7r, Q16_8r)), na.rm = TRUE),
    
    # Right-Wing Authoritarianism: 
    ## First, reverse-code items:
    Q17_1r = 8 - Q17_1,
    Q17_4r = 8 - Q17_4,
    Q17_5r = 8 - Q17_5,
    Q17_7r = 8 - Q17_7,
    
    ## Second, compute index scores from Q17 after reversing the 4 items
    rwa = rowMeans(across(c(Q17_1r, Q17_2, Q17_3, Q17_4r, Q17_5r, Q17_6)), na.rm = TRUE),
    

    # Populist attitudes: compute index scores from Q37
    populist_attitudes = rowMeans(across(paste0("Q37_", 1:8)), na.rm = TRUE)
  )

Analyses From Main Article

Checking internal consistency of indices via Cronbach’s alpha

#Item sets
FBD_items   <- df1 %>% dplyr::select(Q20_1, Q20_2, Q20_3)
POP_items   <- df1 %>% dplyr::select(dplyr::all_of(paste0("Q37_", 1:8))) 
RWA_items   <- df1 %>% dplyr::select(dplyr::all_of(paste0("Q17_", 1:6))) 
SDO_items   <- df1 %>% dplyr::select(dplyr::all_of(c("Q16__1","Q16__2","Q16__3","Q16__4",
                                                     "Q16__5","Q16__6","Q16__7","Q16__8")))
MACH_items  <- df1 %>% dplyr::select(dplyr::all_of(paste0("Q33_", 1:7))) 
NARC_items  <- df1 %>% dplyr::select(dplyr::all_of(paste0("Q34_", 1:7)))
PSY_items   <- df1 %>% dplyr::select(dplyr::all_of(paste0("Q35_", 1:7)))

# Compute alphas; check.keys lets psych reverse-code as needed
a_FBD   <- psych::alpha(FBD_items,   check.keys = TRUE)
a_POP   <- psych::alpha(POP_items,   check.keys = TRUE)
a_RWA   <- psych::alpha(RWA_items,   check.keys = TRUE)
a_SDO   <- psych::alpha(SDO_items,   check.keys = TRUE)
a_MACH  <- psych::alpha(MACH_items,  check.keys = TRUE)
a_NARC  <- psych::alpha(NARC_items,  check.keys = TRUE)
a_PSY   <- psych::alpha(PSY_items,   check.keys = TRUE)

# Rounded values
alpha_fbd  <- round(a_FBD$total$raw_alpha,  2)
alpha_pop  <- round(a_POP$total$raw_alpha,  2)
alpha_rwa  <- round(a_RWA$total$raw_alpha,  2)
alpha_sdo  <- round(a_SDO$total$raw_alpha,  2)
alpha_mach <- round(a_MACH$total$raw_alpha, 2)
alpha_narc <- round(a_NARC$total$raw_alpha, 2)
alpha_psy  <- round(a_PSY$total$raw_alpha,  2)

# Quick table
reliab_tbl <- tibble::tibble(
  scale = c("Feelings of being devalued (FBD)", "Populist attitudes",
            "Right-wing authoritarianism (RWA)", "Social dominance orientation (SDO)",
            "Machiavellianism", "Narcissism", "Psychopathy"),
  items = c(3, 8, 6, 8, 7, 7, 7),
  alpha = c(alpha_fbd, alpha_pop, alpha_rwa, alpha_sdo,
            alpha_mach, alpha_narc, alpha_psy)
)
knitr::kable(reliab_tbl, digits = 2, caption = "Internal consistency (Cronbach’s α) for all multi-item scales.")
Internal consistency (Cronbach’s α) for all multi-item scales.
scale items alpha
Feelings of being devalued (FBD) 3 0.82
Populist attitudes 8 0.82
Right-wing authoritarianism (RWA) 6 0.58
Social dominance orientation (SDO) 8 0.76
Machiavellianism 7 0.78
Narcissism 7 0.87
Psychopathy 7 0.90

Model 1. Tolerance for Presidential Lawbreaking

# Run OLS regression
model1 <- lm(trump_lawbreaking_acceptance ~ education + white + ideology + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + rwa + sdo , data=df1
)

Model 2. Support for Trump Emergency Powers

# Run OLS regression
model2 <- lm(trump_emergency_powers_support ~ education + white + ideology + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + rwa + sdo , data=df1
)

Blockwise variance

# Make a complete-case dataset across all variables
all_vars <- c(
  # outcomes
  "trump_lawbreaking_acceptance","trump_emergency_powers_support",
  # demographics / controls
  "education","white", "gender","political_interest",
  # partisanship
  "trump_voter", "ideology",
  # authoritarian predispositions
  "rwa","sdo",
  # dark traits
  "machiavellianism","narcissism","psychopathy",
  # affect
  "fbd",
  # populism
  "populist_attitudes"
)

df_cc <- df1 %>% dplyr::select(all_of(all_vars)) %>% na.omit()

# Define the conceptual blocks
block_demog  <- c("education","white","gender","political_interest")
block_party  <- c("trump_voter", "ideology")
block_auth   <- c("rwa","sdo")
block_dark   <- c("machiavellianism","narcissism","psychopathy")
block_fbd    <- c("fbd")
block_pop    <- c("populist_attitudes")

blocks_list  <- list(
  "Demographics" = block_demog,
  "Partisanship"            = block_party,
  "Authoritarian predispositions" = block_auth,
  "Dark traits (SD3)"       = block_dark,
  "Affective resentment (FBD)" = block_fbd,
  "Populist attitudes"      = block_pop
)

# Build hierarchical models and compute R2, ΔR2, F-change
run_blockwise <- function(outcome, blocks, data) {
  # sequentially add blocks
  models <- list()
  terms_so_far <- character(0)
  rows <- list()
  
  i <- 0
  for (bn in names(blocks)) {
    i <- i + 1
    terms_so_far <- c(terms_so_far, blocks[[bn]])
    fml <- as.formula(paste(outcome, "~", paste(terms_so_far, collapse = " + ")))
    m <- lm(fml, data = data)
    models[[i]] <- m
    
    # Collect stats
    R2  <- summary(m)$r.squared
    k_new <- length(blocks[[bn]])
    
    if (i == 1) {
      rows[[i]] <- tibble::tibble(
        step = i,
        block = bn,
        k_added = k_new,
        R2 = R2,
        delta_R2 = R2,
        F_change = NA_real_,
        df1 = NA_integer_,
        df2 = NA_integer_,
        p_change = NA_real_
      )
    } else {
      # F change test: nested ANOVA between previous and current model
      a <- anova(models[[i-1]], models[[i]])
      rows[[i]] <- tibble::tibble(
        step = i,
        block = bn,
        k_added = k_new,
        R2 = R2,
        delta_R2 = R2 - summary(models[[i-1]])$r.squared,
        F_change = a$F[2],
        df1 = a$Df[2],
        df2 = a$Res.Df[2],
        p_change = a$`Pr(>F)`[2]
      )
    }
  }
  
  out_tbl <- dplyr::bind_rows(rows)
  list(table = out_tbl, models = models)
}

Blockwise variance for acceptance of presidential lawbreaking

bw_law <- run_blockwise("trump_lawbreaking_acceptance", blocks_list, df_cc)

law_tbl <- bw_law$table %>%
  mutate(
    R2        = round(R2, 3),
    delta_R2  = round(delta_R2, 3),
    F_change  = ifelse(is.na(F_change), NA, round(F_change, 2)),
    p_change  = ifelse(is.na(p_change), NA, scales::pvalue(p_change))
  )

knitr::kable(
  law_tbl,
  align = "lccrrrcc",
  caption = "Blockwise variance decomposition for acceptance of presidential lawbreaking",
  col.names = c("Step","Block","k added","R²","ΔR²","F-change","df1","df2","p")
)
Blockwise variance decomposition for acceptance of presidential lawbreaking
Step Block k added ΔR² F-change df1 df2 p
1 Demographics 4 0.018 0.018 NA NA NA NA
2 Partisanship 2 0.118 0.101 60.00 2 1052 <0.001
3 Authoritarian predispositions 2 0.179 0.061 38.85 2 1050 <0.001
4 Dark traits (SD3) 3 0.326 0.147 75.90 3 1047 <0.001
5 Affective resentment (FBD) 1 0.330 0.005 7.08 1 1046 0.008
6 Populist attitudes 1 0.336 0.006 9.48 1 1045 0.002

Blockwise variance for support for Trump emergency powers

bw_emerg <- run_blockwise("trump_emergency_powers_support", blocks_list, df_cc)

em_tbl <- bw_emerg$table %>%
  mutate(
    R2        = round(R2, 3),
    delta_R2  = round(delta_R2, 3),
    F_change  = ifelse(is.na(F_change), NA, round(F_change, 2)),
    p_change  = ifelse(is.na(p_change), NA, scales::pvalue(p_change))
  )

knitr::kable(
  em_tbl,
  align = "lccrrrcc",
  caption = "Blockwise variance decomposition for support for permanent emergency powers",
  col.names = c("Step","Block","k added","R²","ΔR²","F-change","df1","df2","p")
)
Blockwise variance decomposition for support for permanent emergency powers
Step Block k added ΔR² F-change df1 df2 p
1 Demographics 4 0.041 0.041 NA NA NA NA
2 Partisanship 2 0.254 0.213 150.37 2 1052 <0.001
3 Authoritarian predispositions 2 0.298 0.043 32.50 2 1050 <0.001
4 Dark traits (SD3) 3 0.421 0.123 74.17 3 1047 <0.001
5 Affective resentment (FBD) 1 0.427 0.006 10.48 1 1046 0.001
6 Populist attitudes 1 0.429 0.003 4.61 1 1045 0.032

Reproducing Figures and Tables

Table 1. Regression Results with HC3 Robust SEs

# Robust SEs for model1
coeftest(model1, vcov = vcovHC(model1, type = "HC3"))

# Robust SEs for model2
coeftest(model2, vcov = vcovHC(model2, type = "HC3"))

# HC3 covariance matrices
vc1 <- vcovHC(model1, type = "HC3")
vc2 <- vcovHC(model2, type = "HC3")

# Robust SE vectors (names must match coef order)
se1 <- sqrt(diag(vc1))
se2 <- sqrt(diag(vc2))

# Write LaTeX table with robust SEs
stargazer(
  model1, model2,
  se = list(se1, se2),                 # <- robust SEs
  type = "latex",
  out  = "Output/regression_table_robust.tex",
  title = "Regression Results with HC3 Robust SEs",
  column.labels = c("Tolerance for lawbreaking", "Support for Trump emergency powers"),
  dep.var.labels.include = FALSE,
  report = "vcsp*",                    # coef, SE, p, stars
  digits = 3,
  single.row = TRUE,
  star.char = c(".", "*", "**", "***"),
  star.cutoffs = c(0.1, 0.05, 0.01, 0.001),
  covariate.labels = c(
    "Education","White","Ideology","Gender","Political interest","Trump vote",
    "Feelings of being devalued","Populist attitudes",
    "Psychopathy","Narcissism","Machiavellianism",
    "Right-wing authoritarianism","Social dominance orientation"
  ),
  notes = c("HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001"),
  notes.append = FALSE
)
Regression Results with HC3 Robust SEs
Dependent variable:
(1) (2)
Education -0.054 (0.054) -0.185 (0.050)
p = 0.319 p = 0.0003***
White -0.097 (0.109) -0.110 (0.102)
p = 0.375 p = 0.284
Ideology 0.042 (0.020) 0.063 (0.020)
p = 0.037* p = 0.002**
Gender 0.001 (0.022) 0.013 (0.034)
p = 0.974 p = 0.695
Political interest -0.030 (0.060) 0.064 (0.060)
p = 0.623 p = 0.283
Trump vote 0.770 (0.122) 1.295 (0.119)
p = 0.000*** p = 0.000***
Feelings of being devalued 0.116 (0.039) 0.126 (0.039)
p = 0.003** p = 0.002**
Populist attitudes -0.260 (0.094) -0.175 (0.088)
p = 0.006** p = 0.048*
Psychopathy 0.570 (0.073) 0.302 (0.071)
p = 0.000*** p = 0.00003***
Narcissism 0.324 (0.078) 0.515 (0.076)
p = 0.00004*** p = 0.000***
Machiavellianism 0.164 (0.100) 0.256 (0.092)
p = 0.099. p = 0.006**
Right-wing authoritarianism 0.029 (0.053) 0.160 (0.056)
p = 0.581 p = 0.005**
Social dominance orientation 0.226 (0.057) 0.210 (0.056)
p = 0.0001*** p = 0.0002***
Constant -0.926 (0.491) -2.182 (0.453)
p = 0.060. p = 0.00001***
Observations 1,059 1,059
R2 0.336 0.429
Adjusted R2 0.328 0.422
Residual Std. Error (df = 1045) 1.632 1.574
F Statistic (df = 13; 1045) 40.695*** 60.406***
Note: HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Figure 1. Predictors of Tolerance for Illiberal Governance

# Make z-scored copies of all variables
preds_all <- c("education","white","ideology","gender","political_interest",
               "trump_voter","fbd","populist_attitudes","psychopathy",
               "narcissism","machiavellianism","rwa","sdo")

dfz <- df1 %>%
  mutate(
    across(all_of(preds_all), ~ as.numeric(.x), .names = "{.col}") %>%
      { mutate(., across(all_of(preds_all), ~ as.numeric(scale(.x)),
                         .names = "{.col}_z")) } %>%
      mutate(lawbreaking_z = as.numeric(scale(trump_lawbreaking_acceptance)),
             emerpowers_z  = as.numeric(scale(trump_emergency_powers_support)))
  )

# Fit models on z-variables
m1z <- lm(lawbreaking_z ~ education_z + white_z + ideology_z + gender_z +
            political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
            psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
          data = dfz)

m2z <- lm(emerpowers_z ~ education_z + white_z + ideology_z + gender_z +
            political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
            psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
          data = dfz)

# HC3 robust VCOVs for both standardized models
vc1 <- vcovHC(m1z, type = "HC3")
vc2 <- vcovHC(m2z, type = "HC3")

# Tidy with HC3 95% and 99% CIs + p-values
df1_95 <- tidy(m1z, conf.int = TRUE, vcov = vc1) %>%
  mutate(Model = "Tolerance for Trump's lawbreaking")
df2_95 <- tidy(m2z, conf.int = TRUE, vcov = vc2) %>%
  mutate(Model = "Support for Trump emergency powers")

df1_99 <- tidy(m1z, conf.int = TRUE, conf.level = 0.99, vcov = vc1) %>%
  select(term, conf.low, conf.high) %>%
  rename(conf.low2 = conf.low, conf.high2 = conf.high) %>%
  mutate(Model = "Tolerance for Trump's lawbreaking")

df2_99 <- tidy(m2z, conf.int = TRUE, conf.level = 0.99, vcov = vc2) %>%
  select(term, conf.low, conf.high) %>%
  rename(conf.low2 = conf.low, conf.high2 = conf.high) %>%
  mutate(Model = "Support for Trump emergency powers")

ci99_df <- bind_rows(df1_99, df2_99)

coef_df <- bind_rows(df1_95, df2_95) %>%
  left_join(ci99_df, by = c("term","Model")) %>%
  filter(term != "(Intercept)") %>%
  mutate(term = case_when(
    term == "education_z" ~ "Education",
    term == "white_z" ~ "White",
    term == "ideology_z" ~ "Ideology",
    term == "gender_z" ~ "Gender",
    term == "political_interest_z" ~ "Political interest",
    term == "trump_voter_z" ~ "Trump vote",
    term == "fbd_z" ~ "Feelings of being devalued",
    term == "populist_attitudes_z" ~ "Populist attitudes",
    term == "psychopathy_z" ~ "Psychopathy",
    term == "narcissism_z" ~ "Narcissism",
    term == "machiavellianism_z" ~ "Machiavellianism",
    term == "rwa_z" ~ "Right-wing authoritarianism",
    term == "sdo_z" ~ "Social dominance orientation",
    TRUE ~ term
  ))

# Order terms from top to bottom
order_terms <- c("Education","White","Ideology","Gender","Political interest",
                 "Trump vote","Feelings of being devalued","Populist attitudes",
                 "Psychopathy","Narcissism","Machiavellianism",
                 "Right-wing authoritarianism","Social dominance orientation")
coef_df <- coef_df %>% mutate(term = factor(term, levels = rev(order_terms)))

# Identify terms significant at p<.05 in each model (HC3), then flag those significant in BOTH
sig_by_model <- coef_df %>%
  mutate(sig = p.value < 0.05) %>%
  select(term, Model, sig) %>%
  tidyr::pivot_wider(names_from = Model, values_from = sig)

sig_in_both <- sig_by_model %>%
  mutate(in_both = `Tolerance for Trump's lawbreaking` & `Support for Trump emergency powers`) %>%
  filter(in_both) %>%
  pull(term) %>% as.character()

# Vertical offset so points/intervals don’t overlap
offset <- 0.18
coef_df <- coef_df %>%
  mutate(term_id = as.numeric(term),
         y = ifelse(Model == "Support for Trump emergency powers",
                    term_id + offset, term_id - offset))

# Shading only for predictors significant (HC3, p<.05) in BOTH models
band_df <- coef_df %>%
  distinct(term, term_id) %>%
  filter(as.character(term) %in% sig_in_both) %>%
  transmute(ymin = term_id - 0.5, ymax = term_id + 0.5)

# Plot
p_better_robust <- ggplot(coef_df, aes(y = y, x = estimate, shape = Model)) +
  # background bands for terms significant in both models (HC3)
  geom_rect(data = band_df,
            aes(xmin = -Inf, xmax = Inf, ymin = ymin, ymax = ymax),
            inherit.aes = FALSE, fill = "grey90", alpha = 0.7) +
  # 99% CI (thin, light)
  geom_errorbarh(aes(xmin = conf.low2, xmax = conf.high2), height = 0,
                 linewidth = 0.4, color = "gray45", alpha = 0.5) +
  # 95% CI (thicker, dark)
  geom_errorbarh(aes(xmin = conf.low, xmax = conf.high), height = 0,
                 linewidth = 0.7, color = "gray25") +
  # points
  geom_point(size = 3, color = "black", fill = "white", stroke = 0.9) +
  geom_vline(xintercept = 0, linetype = "dotted") +
  scale_shape_manual(values = c(
    "Support for Trump emergency powers" = 16,  # solid circle
    "Tolerance for Trump's lawbreaking"  = 21   # open circle
  )) +
  scale_y_continuous(
    breaks = seq_along(levels(coef_df$term)),
    labels = levels(coef_df$term),
    expand = expansion(mult = c(0.02, 0.05))
  ) +
  labs(
    x = "Standardized coefficient (β)",
    y = NULL,
    title = "",
    caption = "Error bars show 95% (dark) and 99% (light) CIs with HC3 robust standard errors.\nShaded rows: predictors significant at p<.05 in both models (HC3)."
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    panel.grid.minor = element_blank(),
    plot.caption = element_text(size = 10, face = "italic", hjust = 0.5)
  )

p_better_robust # Display the plot

# Save the plot as PNG in the Output folder
ggsave(filename = "Output/figure1.png",
       plot = p_better_robust, width = 8, height = 9.5, dpi = 300)

Figure 2. Prevalence of Agreement with Dark Personality Traits (n=1,009)

set.seed(11)

# Set cutoff at level 4
cutoff <- 4

dark_long <- df1 %>%
  select(machiavellianism, narcissism, psychopathy) %>%
  pivot_longer(everything(), names_to = "trait", values_to = "score") %>%
  filter(!is.na(score)) %>%
  mutate(trait = factor(trait,
                        levels = c("machiavellianism","narcissism","psychopathy"),
                        labels = c("Machiavellianism","Narcissism","Psychopathy")))

above_df <- dark_long %>%
  group_by(trait) %>%
  summarise(pct = 100 * mean(score >= cutoff), .groups = "drop") %>%
  mutate(label = sprintf("%.1f%%", pct))

pos_df <- tibble(trait = levels(dark_long$trait),
                 xnum  = as.numeric(factor(trait, levels = levels(dark_long$trait))))

lab_df <- pos_df %>%
  left_join(above_df, by = "trait") %>%
  transmute(trait,
            x = xnum + 0.28,
            y = 4.55,
            label)

p_sina_violin <-
  ggplot(dark_long, aes(x = trait, y = score)) +
  # Fill violin red, then mask below cutoff so red only appears ≥ 4
  geom_violin(fill = "red", alpha = 0.22, color = NA, trim = FALSE) +
  annotate("rect", xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = cutoff,
           fill = "white", alpha = 1) +
  # Re-draw horizontal level lines (1..5) on top of the mask
  geom_hline(yintercept = 1:5, color = "#E0E0E0", linewidth = 0.4) +
  # Re-draw violin outline
  geom_violin(fill = NA, color = "black", linewidth = 0.9, trim = FALSE) +
  # Data points with vertical jitter
  geom_sina(
    maxwidth = 0.75,
    alpha    = 0.25,
    size     = 1.2,
    scale    = "area",
    method   = "density",
    position = position_jitter(width = 0, height = 0.06)
  ) +
  # Boxplot overlay
  geom_boxplot(width = 0.14, outlier.shape = NA, linewidth = 0.7, fill = NA) +
  # Inline percentage of respondents ≥ 4 label
  geom_text(data = lab_df, aes(x = x, y = y, label = label),
            inherit.aes = FALSE, color = "#d4563f", fontface = "bold", size = 4) +
  scale_y_continuous(
    breaks = 1:5, limits = c(1, 5),
    labels = c("(1) strongly\ndisagree", "(2) disagree", "(3) neutral",
               "(4) agree", "(5) strongly\nagree")
  ) +
  labs(x = NULL, y = "Average scale score") +
  theme_minimal(base_size = 12) +
  theme(
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),  # keep only horizontal level lines
    panel.grid.major.y = element_blank(),  # we draw our own to sit above the mask
    legend.position = "none"
  )

p_sina_violin # Display plot

# Save the plot as PNG in the Output folder
ggsave("Output/figure2.png",
       p_sina_violin, width = 9, height = 5, dpi = 300)

Model diagnostics

Normality assumption

residuals1 <- residuals(model1)
residuals2 <- residuals(model2)

shapiro.test(residuals1)
shapiro.test(residuals2)

hist(residuals1)

hist(residuals2)

Residual diagnostics indicate approximate normality. Although Shapiro-Wilk tests reject exact normality (as expected in large samples), histograms of residuals show distributions that are symmetric and bell-shaped, consistent with OLS assumptions.

No multicollinearity assumption

vif(model1)
##          education              white           ideology             gender 
##           1.108841           1.106819           1.411191           1.009235 
## political_interest        trump_voter                fbd populist_attitudes 
##           1.214926           1.330728           1.293492           1.311497 
##        psychopathy         narcissism   machiavellianism                rwa 
##           1.646804           1.668610           1.602205           1.310353 
##                sdo 
##           1.369364
vif(model2)
##          education              white           ideology             gender 
##           1.108841           1.106819           1.411191           1.009235 
## political_interest        trump_voter                fbd populist_attitudes 
##           1.214926           1.330728           1.293492           1.311497 
##        psychopathy         narcissism   machiavellianism                rwa 
##           1.646804           1.668610           1.602205           1.310353 
##                sdo 
##           1.369364

Variance inflation factors (VIFs) are all below 2, indicating no evidence of problematic multicollinearity among predictors.

Homoscedasticity - Breusch-Pagan test

bptest(model1)
## 
##  studentized Breusch-Pagan test
## 
## data:  model1
## BP = 89.908, df = 13, p-value = 0.0000000000001455
bptest(model2)
## 
##  studentized Breusch-Pagan test
## 
## data:  model2
## BP = 79.255, df = 13, p-value = 0.00000000001523

Breusch-Pagan test finds evidence of homoscedasticity. Models require HC3 Robust SEs.

Appendix Material

Table A.1. Lawbreaking model with and without right-wing authoritarianism (HC3 robust SEs)

# Run OLS regression
model1_no_rwa <- lm(trump_lawbreaking_acceptance ~ education + white + ideology + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + sdo , data=df1
)

# HC3 covariance matrices
vc1 <- vcovHC(model1, type = "HC3")
vc1_no_rwa <- vcovHC(model1_no_rwa, type = "HC3")

# Robust SE vectors 
se1 <- sqrt(diag(vc1))
se1_no_rwa <- sqrt(diag(vc1_no_rwa))

# Write LaTeX table with robust SEs
stargazer(
  model1, model1_no_rwa, 
  se = list(se1, se1_no_rwa),                 # <- robust SEs
  type = "latex",
  out  = "Output/regression_lawbreaking_robust_no_rwa.tex",
  title = "Regression Results (HC3 robust standard errors)",
  column.labels = c("Lawbreaking", "Lawbreaking (no RWA)"),
  dep.var.labels.include = FALSE,
  report = "vcsp*",                    # coef, SE, p, stars
  digits = 3,
  single.row = TRUE,
  star.char = c(".", "*", "**", "***"),
  star.cutoffs = c(0.1, 0.05, 0.01, 0.001),
  notes = c("HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001"),
  notes.append = FALSE
)
Table A.1 — Lawbreaking model with and without RWA (HC3 robust SEs)
Dependent variable:
(1) (2)
Education -0.054 (0.054) -0.056 (0.053)
p = 0.319 p = 0.294
White -0.097 (0.109) -0.097 (0.109)
p = 0.375 p = 0.371
Ideology 0.042 (0.020) 0.045 (0.019)
p = 0.037* p = 0.021*
Gender 0.001 (0.022) 0.001 (0.022)
p = 0.974 p = 0.979
Political interest -0.030 (0.060) -0.031 (0.060)
p = 0.623 p = 0.610
Trump vote 0.770 (0.122) 0.782 (0.119)
p = 0.000*** p = 0.000***
Feelings of being devalued 0.116 (0.039) 0.115 (0.039)
p = 0.003** p = 0.004**
Populist attitudes -0.260 (0.094) -0.259 (0.094)
p = 0.006** p = 0.006**
Psychopathy 0.570 (0.073) 0.566 (0.072)
p = 0.000*** p = 0.000***
Narcissism 0.324 (0.078) 0.326 (0.078)
p = 0.00004*** p = 0.00003***
Machiavellianism 0.164 (0.100) 0.165 (0.099)
p = 0.099. p = 0.097.
Right-wing authoritarianism 0.029 (0.053)
p = 0.581
Social dominance orientation 0.226 (0.057) 0.230 (0.056)
p = 0.0001*** p = 0.00004***
Constant -0.926 (0.491) -0.834 (0.453)
p = 0.060. p = 0.066.
Observations 1,059 1,059
R2 0.336 0.336
Adjusted R2 0.328 0.328
Residual Std. Error 1.632 (df = 1045) 1.631 (df = 1046)
F Statistic 40.695*** (df = 13; 1045) 44.092*** (df = 12; 1046)
Note: HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Table A.2. Emergency Powers model with and without right-wing authoritarianism (HC3 robust SEs)

# Run OLS regression
model2_no_rwa <- lm(trump_emergency_powers_support ~ education + white + ideology + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + sdo , data=df1
)

# HC3 covariance matrices
vc2 <- vcovHC(model2, type = "HC3")
vc2_no_rwa <- vcovHC(model2_no_rwa, type = "HC3")

# Robust SE vectors 
se2 <- sqrt(diag(vc2))
se2_no_rwa <- sqrt(diag(vc2_no_rwa))


# Write LaTeX table with robust SEs
stargazer(
  model2, model2_no_rwa,
  se = list(se2, se2_no_rwa),                 # <- robust SEs
  type = "latex",
  out  = "Output/regression_emergencypowers_robust_no_rwa.tex",
  title = "Regression Results (HC3 robust standard errors)",
  column.labels = c("Emergency powers", "Emergency powers (no RWA)"),
  dep.var.labels.include = FALSE,
  report = "vcsp*",                    # coef, SE, p, stars
  digits = 3,
  single.row = TRUE,
  star.char = c(".", "*", "**", "***"),
  star.cutoffs = c(0.1, 0.05, 0.01, 0.001),
  notes = c("HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001"),
  notes.append = FALSE
)
Table A.2 — Emergency Powers model with and without RWA (HC3 robust SEs)
Dependent variable:
(1) (2)
Education -0.185 (0.050) -0.198 (0.050)
p = 0.0003*** p = 0.0001***
White -0.110 (0.102) -0.113 (0.103)
p = 0.284 p = 0.271
Ideology 0.063 (0.020) 0.080 (0.020)
p = 0.002** p = 0.00005***
Gender 0.013 (0.034) 0.013 (0.038)
p = 0.695 p = 0.737
Political interest 0.064 (0.060) 0.059 (0.060)
p = 0.283 p = 0.329
Trump vote 1.295 (0.119) 1.364 (0.117)
p = 0.000*** p = 0.000***
Feelings of being devalued 0.126 (0.039) 0.122 (0.039)
p = 0.002** p = 0.002**
Populist attitudes -0.175 (0.088) -0.171 (0.089)
p = 0.048* p = 0.054.
Psychopathy 0.302 (0.071) 0.277 (0.070)
p = 0.00003*** p = 0.0001***
Narcissism 0.515 (0.076) 0.522 (0.076)
p = 0.000*** p = 0.000***
Machiavellianism 0.256 (0.092) 0.262 (0.092)
p = 0.006** p = 0.005**
Right-wing authoritarianism 0.160 (0.056)
p = 0.005**
Social dominance orientation 0.210 (0.056) 0.233 (0.055)
p = 0.0002*** p = 0.00003***
Constant -2.182 (0.453) -1.676 (0.420)
p = 0.00001*** p = 0.0001***
Observations 1,059 1,059
R2 0.429 0.424
Adjusted R2 0.422 0.417
Residual Std. Error 1.574 (df = 1045) 1.580 (df = 1046)
F Statistic 60.406*** (df = 13; 1045) 64.139*** (df = 12; 1046)
Note: HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Table A.3. Models 1 and 2, replacing ideology with Republican party ID (HC3 robust SEs)

# Run Model 1 with Republican Party ID instead of ideology
model1_gop <- lm(trump_lawbreaking_acceptance ~ education + white + republican + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + rwa + sdo , data=df1
)

# Run Model 2 with Republican Party ID instead of ideology
model2_gop <- lm(trump_emergency_powers_support ~ education + white + republican + gender +
    political_interest + trump_voter + fbd + populist_attitudes + psychopathy + narcissism + machiavellianism + rwa + sdo , data=df1
)

# HC3 covariance matrices
vc1_gop <- vcovHC(model1_gop, type = "HC3")
vc2_gop <- vcovHC(model2_gop, type = "HC3")

# Robust SE vectors (names must match coef order)
se1_gop <- sqrt(diag(vc1_gop))
se2_gop <- sqrt(diag(vc2_gop))

# Write LaTeX table with robust SEs
stargazer(
  model1_gop, model2_gop, 
  se = list(se1_gop, se2_gop),                 # <- robust SEs
  type = "latex",
  out  = "Output/regression_models_robust_gop.tex",
  title = "Models 1 and 2, replacing ideology with Republican party ID (HC3 robust SEs)",
  column.labels = c("Lawbreaking", "Emergency powers"),
  dep.var.labels.include = FALSE,
  report = "vcsp*",                    # coef, SE, p, stars
  digits = 3,
  single.row = TRUE,
  star.char = c(".", "*", "**", "***"),
  star.cutoffs = c(0.1, 0.05, 0.01, 0.001),
  notes = c("HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001"),
  notes.append = FALSE
)
Table A.3 — Models 1 and 2 replacing Ideology with Republican Party ID (HC3 robust SEs)
Dependent variable:
(1) (2)
Education -0.063 (0.054) -0.199 (0.051)
p = 0.246 p = 0.0001***
White -0.107 (0.109) -0.128 (0.102)
p = 0.329 p = 0.211
Republican ID 0.262 (0.141) 0.439 (0.143)
p = 0.064. p = 0.003**
Gender 0.0004 (0.022) 0.013 (0.035)
p = 0.988 p = 0.715
Political interest -0.029 (0.060) 0.064 (0.059)
p = 0.630 p = 0.278
Trump vote 0.670 (0.141) 1.119 (0.142)
p = 0.00001*** p = 0.000***
Feelings of being devalued 0.120 (0.039) 0.132 (0.039)
p = 0.002** p = 0.001***
Populist attitudes -0.257 (0.094) -0.170 (0.088)
p = 0.007** p = 0.055.
Psychopathy 0.570 (0.073) 0.301 (0.071)
p = 0.000*** p = 0.00003***
Narcissism 0.341 (0.078) 0.540 (0.076)
p = 0.00002*** p = 0.000***
Machiavellianism 0.167 (0.100) 0.260 (0.092)
p = 0.094. p = 0.005**
Right-wing authoritarianism 0.049 (0.052) 0.188 (0.055)
p = 0.353 p = 0.001***
Social dominance orientation 0.235 (0.057) 0.222 (0.057)
p = 0.00004*** p = 0.0001***
Constant -0.857 (0.497) -2.066 (0.462)
p = 0.085. p = 0.00001***
Observations 1,059 1,059
R2 0.336 0.429
Adjusted R2 0.327 0.422
Residual Std. Error (df = 1045) 1.633 1.574
F Statistic (df = 13; 1045) 40.598*** 60.388***
Note: HC3 robust standard errors in parentheses. . p<0.1; * p<0.05; ** p<0.01; *** p<0.001

Figure A.1. Lawbreaking Models

# Build a z-scored dataset that includes both ideology and republican
preds_all <- c("education","white","ideology","republican","gender","political_interest",
               "trump_voter","fbd","populist_attitudes","psychopathy",
               "narcissism","machiavellianism","rwa","sdo")

dfz_rb <- df1 %>%
  mutate(across(all_of(preds_all), ~ as.numeric(.x))) %>%
  mutate(across(all_of(preds_all), ~ as.numeric(scale(.x)), .names = "{.col}_z")) %>%
  mutate(lawbreaking_z = as.numeric(scale(trump_lawbreaking_acceptance)),
         emerpowers_z  = as.numeric(scale(trump_emergency_powers_support)))

# Fit standardized lawbreaking models 
m1z_base <- lm(lawbreaking_z ~ education_z + white_z + ideology_z + gender_z +
                 political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                 psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
               data = dfz_rb)

m1z_norwa <- lm(lawbreaking_z ~ education_z + white_z + ideology_z + gender_z +
                  political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                  psychopathy_z + narcissism_z + machiavellianism_z + sdo_z,
                data = dfz_rb)

m1z_gop <- lm(lawbreaking_z ~ education_z + white_z + republican_z + gender_z +
                political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
              data = dfz_rb)

# Tidy with HC3 95% & 99% CIs
tidy_hc3 <- function(m, model_name){
  vc <- vcovHC(m, type = "HC3")
  d95 <- tidy(m, conf.int = TRUE, vcov = vc) %>% mutate(Model = model_name)
  d99 <- tidy(m, conf.int = TRUE, conf.level = 0.99, vcov = vc) %>%
    select(term, conf.low, conf.high) %>%
    rename(conf.low2 = conf.low, conf.high2 = conf.high) %>%
    mutate(Model = model_name)
  list(d95 = d95, d99 = d99)
}

L1 <- tidy_hc3(m1z_base,  "As reported in article")
L2 <- tidy_hc3(m1z_norwa, "Without RWA")
L3 <- tidy_hc3(m1z_gop,   "Party ID instead of ideology")

df95 <- bind_rows(L1$d95, L2$d95, L3$d95)
df99 <- bind_rows(L1$d99, L2$d99, L3$d99)

coef_df <- df95 %>%
  left_join(df99, by = c("term","Model")) %>%
  filter(term != "(Intercept)")

# Clean labels and order
coef_df <- coef_df %>%
  mutate(term = case_when(
    term == "education_z"            ~ "Education",
    term == "white_z"                ~ "White",
    term == "ideology_z"             ~ "Ideology",
    term == "republican_z"           ~ "Republican ID",
    term == "gender_z"               ~ "Gender",
    term == "political_interest_z"   ~ "Political interest",
    term == "trump_voter_z"          ~ "Trump vote",
    term == "fbd_z"                  ~ "Feelings of being devalued",
    term == "populist_attitudes_z"   ~ "Populist attitudes",
    term == "psychopathy_z"          ~ "Psychopathy",
    term == "narcissism_z"           ~ "Narcissism",
    term == "machiavellianism_z"     ~ "Machiavellianism",
    term == "rwa_z"                  ~ "Right-wing authoritarianism",
    term == "sdo_z"                  ~ "Social dominance orientation",
    TRUE ~ term
  ))

order_terms <- c("Education","White","Ideology","Republican ID","Gender","Political interest",
                 "Trump vote","Feelings of being devalued","Populist attitudes",
                 "Psychopathy","Narcissism","Machiavellianism",
                 "Right-wing authoritarianism","Social dominance orientation")
coef_df <- coef_df %>%
  mutate(term = factor(term, levels = rev(order_terms)))

# Vertical offsets to separate the three model markers
offset <- 0.22
coef_df <- coef_df %>%
  mutate(term_id = as.numeric(term),
         y = case_when(
           Model == "As reported in article" ~ term_id + offset,
           Model == "Without RWA"   ~ term_id,
           TRUE                ~ term_id - offset   # GOP swap
         ))

# Plot
p_law_robust_set <-
  ggplot(coef_df, aes(y = y, x = estimate, shape = Model)) +
  # 99% CI light
  geom_errorbarh(aes(xmin = conf.low2, xmax = conf.high2),
                 height = 0, linewidth = 0.4, color = "gray75", alpha = 0.6) +
  # 95% CI dark
  geom_errorbarh(aes(xmin = conf.low, xmax = conf.high),
                 height = 0, linewidth = 0.7, color = "gray25") +
  # points
  geom_point(size = 3, color = "black", fill = "white", stroke = 0.9) +
  geom_vline(xintercept = 0, linetype = "dotted") +
  scale_shape_manual(values = c("As reported in article" = 16, "Without RWA" = 21, "Party ID instead of ideology" = 17)) +
  scale_y_continuous(
    breaks = seq_along(levels(coef_df$term)),
    labels = levels(coef_df$term),
    expand = expansion(mult = c(0.02, 0.06))
  ) +
  labs(
    title = "",
    x = "Standardized coefficient (β)",
    y = NULL,
    caption = "Error bars show 95% (dark) and 99% (light) CIs with HC3 robust SEs.\nModels use standardized variables."
  ) +
  theme_minimal(base_size = 14) +
  theme(
    legend.position = "bottom",
    legend.title = element_blank(),
    panel.grid.minor = element_blank(),
    plot.caption = element_text(size = 10, face = "italic", hjust = 0.5)
  )

p_law_robust_set

# Save the plot as PNG in the Output folder
ggsave("Output/figurea1.png",
       p_law_robust_set, width = 8, height = 9.5, dpi = 300)

Figure A.2. Emergency Powers Models

# Assumes dfz_rb and tidy_hc3() already created in the previous chunk

# Fit standardized emergency-powers models (baseline / no-RWA / GOP swap)
m2z_base <- lm(emerpowers_z ~ education_z + white_z + ideology_z + gender_z +
                 political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                 psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
               data = dfz_rb)

m2z_norwa <- lm(emerpowers_z ~ education_z + white_z + ideology_z + gender_z +
                  political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                  psychopathy_z + narcissism_z + machiavellianism_z + sdo_z,
                data = dfz_rb)

m2z_gop <- lm(emerpowers_z ~ education_z + white_z + republican_z + gender_z +
                political_interest_z + trump_voter_z + fbd_z + populist_attitudes_z +
                psychopathy_z + narcissism_z + machiavellianism_z + rwa_z + sdo_z,
              data = dfz_rb)

# Tidy with HC3 95% & 99% CIs 
E1 <- tidy_hc3(m2z_base,  "As reported in article")
E2 <- tidy_hc3(m2z_norwa, "Without RWA")
E3 <- tidy_hc3(m2z_gop,   "Party ID instead of ideology")

df95_e <- dplyr::bind_rows(E1$d95, E2$d95, E3$d95)
df99_e <- dplyr::bind_rows(E1$d99, E2$d99, E3$d99)

coef_df2 <- df95_e %>%
  dplyr::left_join(df99_e, by = c("term","Model")) %>%
  dplyr::filter(term != "(Intercept)") %>%
  dplyr::mutate(term = dplyr::case_when(
    term == "education_z"            ~ "Education",
    term == "white_z"                ~ "White",
    term == "ideology_z"             ~ "Ideology",
    term == "republican_z"           ~ "Republican ID",
    term == "gender_z"               ~ "Gender",
    term == "political_interest_z"   ~ "Political interest",
    term == "trump_voter_z"          ~ "Trump vote",
    term == "fbd_z"                  ~ "Feelings of being devalued",
    term == "populist_attitudes_z"   ~ "Populist attitudes",
    term == "psychopathy_z"          ~ "Psychopathy",
    term == "narcissism_z"           ~ "Narcissism",
    term == "machiavellianism_z"     ~ "Machiavellianism",
    term == "rwa_z"                  ~ "Right-wing authoritarianism",
    term == "sdo_z"                  ~ "Social dominance orientation",
    TRUE ~ term
  ))

order_terms2 <- c("Education","White","Ideology","Republican ID","Gender","Political interest",
                  "Trump vote","Feelings of being devalued","Populist attitudes",
                  "Psychopathy","Narcissism","Machiavellianism",
                  "Right-wing authoritarianism","Social dominance orientation")

coef_df2 <- coef_df2 %>%
  dplyr::mutate(term = factor(term, levels = rev(order_terms2)),
                term_id = as.numeric(term))

# Vertical offsets
offset <- 0.22
coef_df2 <- coef_df2 %>%
  dplyr::mutate(y = dplyr::case_when(
    Model == "As reported in article"     ~ term_id + offset,
    Model == "Without RWA"                ~ term_id,
    TRUE                                   ~ term_id - offset   # Party ID instead of ideology
  ))

# Plot
p_emerg_robust_set <-
  ggplot2::ggplot(coef_df2, ggplot2::aes(y = y, x = estimate, shape = Model)) +
  ggplot2::geom_errorbarh(ggplot2::aes(xmin = conf.low2, xmax = conf.high2),
                          height = 0, linewidth = 0.4, color = "gray75", alpha = 0.6) +
  ggplot2::geom_errorbarh(ggplot2::aes(xmin = conf.low, xmax = conf.high),
                          height = 0, linewidth = 0.7, color = "gray25") +
  ggplot2::geom_point(size = 3, color = "black", fill = "white", stroke = 0.9) +
  ggplot2::geom_vline(xintercept = 0, linetype = "dotted") +
  ggplot2::scale_shape_manual(values = c(
    "As reported in article" = 16,
    "Without RWA"            = 21,
    "Party ID instead of ideology" = 17
  )) +
  ggplot2::scale_y_continuous(
    breaks = seq_along(levels(coef_df2$term)),
    labels = levels(coef_df2$term),
    expand = ggplot2::expansion(mult = c(0.02, 0.06))
  ) +
  ggplot2::labs(
    title = "",
    x = "Standardized coefficient (β)",
    y = NULL,
    caption = "Error bars show 95% (dark) and 99% (light) CIs with HC3 robust SEs.\nModels use standardized variables."
  ) +
  ggplot2::theme_minimal(base_size = 14) +
  ggplot2::theme(
    legend.position = "bottom",
    legend.title = ggplot2::element_blank(),
    panel.grid.minor = ggplot2::element_blank(),
    plot.caption = ggplot2::element_text(size = 10, face = "italic", hjust = 0.5)
  )

p_emerg_robust_set

# Save the plot as PNG in the Output folder
ggplot2::ggsave("Output/figurea2.png",
                p_emerg_robust_set, width = 8, height = 9.5, dpi = 300)

Table A.4. Relative Importance (LMG) by Model

library(relaimpo) 
# Compute LMG values for each model
get_lmg <- function(model, model_label) {
  x <- calc.relimp(model, type = "lmg")
  tibble(
    Predictor = names(x$lmg),
    LMG = unname(x$lmg),
    Model = model_label
  )
}

lmg_df <- bind_rows(
  get_lmg(model1, "Lawbreaking"),
  get_lmg(model2, "Emergency powers")
) %>%
  arrange(Model, desc(LMG)) %>%
  mutate(LMG = round(LMG, 3))

# Export using modelsummary::datasummary_df
datasummary_df(
  lmg_df,
  title = "Relative Importance (LMG) by Model",
  output = "Output/lmg_relative_importance.tex",
  align = "lcc",
  fmt = "%.3f",
  notes = "Entries are Lindeman–Merenda–Gold (LMG) relative-importance values computed with relaimpo::calc.relimp(type = 'lmg')."
)
Relative Importance (LMG) by Model
Predictor LMG Model
Entries are Lindeman–Merenda–Gold (LMG) relative-importance values computed with relaimpo::calc.relimp(type = 'lmg').
trump\_voter \num{0.109} Emergency powers
narcissism \num{0.074} Emergency powers
psychopathy \num{0.057} Emergency powers
ideology \num{0.047} Emergency powers
sdo \num{0.044} Emergency powers
machiavellianism \num{0.030} Emergency powers
rwa \num{0.027} Emergency powers
fbd \num{0.020} Emergency powers
education \num{0.009} Emergency powers
political\_interest \num{0.006} Emergency powers
populist\_attitudes \num{0.002} Emergency powers
white \num{0.002} Emergency powers
gender \num{0.001} Emergency powers
psychopathy \num{0.110} Lawbreaking
narcissism \num{0.050} Lawbreaking
sdo \num{0.047} Lawbreaking
trump\_voter \num{0.041} Lawbreaking
fbd \num{0.024} Lawbreaking
machiavellianism \num{0.023} Lawbreaking
ideology \num{0.023} Lawbreaking
rwa \num{0.006} Lawbreaking
populist\_attitudes \num{0.006} Lawbreaking
white \num{0.003} Lawbreaking
political\_interest \num{0.002} Lawbreaking
education \num{0.001} Lawbreaking
gender \num{0.000} Lawbreaking

Session Info

─ Session info ─────────────────────────────────────────────────────────────── setting value version R version 4.5.1 (2025-06-13) os macOS Sequoia 15.6.1 system aarch64, darwin20 ui X11 language (EN) collate en_US.UTF-8 ctype en_US.UTF-8 tz Europe/Zurich date 2025-10-09 pandoc 3.6.3 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown) quarto 1.7.32 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/quarto

─ Packages ─────────────────────────────────────────────────────────────────── package * version date (UTC) lib source abind 1.4-8 2024-09-12 [2] CRAN (R 4.5.0) assertthat 0.2.1 2019-03-21 [2] CRAN (R 4.5.0) backports 1.5.0 2024-05-23 [2] CRAN (R 4.5.0) bit 4.6.0 2025-03-06 [2] CRAN (R 4.5.0) bit64 4.6.0-1 2025-01-16 [2] CRAN (R 4.5.0) boot * 1.3-31 2024-08-28 [2] CRAN (R 4.5.1) broom * 1.0.10 2025-09-13 [2] CRAN (R 4.5.0) broom.mixed * 0.2.9.6 2024-10-15 [2] CRAN (R 4.5.0) bslib 0.9.0 2025-01-30 [2] CRAN (R 4.5.0) cachem 1.1.0 2024-05-16 [2] CRAN (R 4.5.0) car * 3.1-3 2024-09-27 [2] CRAN (R 4.5.0) carData * 3.0-5 2022-01-06 [2] CRAN (R 4.5.0) cellranger 1.1.0 2016-07-27 [2] CRAN (R 4.5.0) checkmate 2.3.3 2025-08-18 [2] CRAN (R 4.5.0) cli 3.6.5 2025-04-23 [2] CRAN (R 4.5.0) cluster * 2.1.8.1 2025-03-12 [2] CRAN (R 4.5.1) coda 0.19-4.1 2024-01-31 [2] CRAN (R 4.5.0) codetools 0.2-20 2024-03-31 [2] CRAN (R 4.5.1) corpcor 1.6.10 2021-09-16 [1] CRAN (R 4.5.0) corrplot * 0.95 2024-10-14 [2] CRAN (R 4.5.0) crayon 1.5.3 2024-06-20 [2] CRAN (R 4.5.0) data.table 1.17.8 2025-07-10 [2] CRAN (R 4.5.0) DBI 1.2.3 2024-06-02 [2] CRAN (R 4.5.0) digest 0.6.37 2024-08-19 [2] CRAN (R 4.5.0) dplyr * 1.1.4 2023-11-17 [2] CRAN (R 4.5.0) emmeans 1.11.2-8 2025-08-27 [2] CRAN (R 4.5.0) estimability 1.5.1 2024-05-12 [2] CRAN (R 4.5.0) estimatr * 1.0.6 2025-02-28 [2] CRAN (R 4.5.0) evaluate 1.0.5 2025-08-27 [2] CRAN (R 4.5.0) factoextra * 1.0.7 2020-04-01 [2] CRAN (R 4.5.0) fansi 1.0.6 2023-12-08 [2] CRAN (R 4.5.0) farver 2.1.2 2024-05-13 [2] CRAN (R 4.5.0) fastmap 1.2.0 2024-05-15 [2] CRAN (R 4.5.0) fmsb * 0.7.6 2024-01-19 [2] CRAN (R 4.5.0) forcats * 1.0.1 2025-09-25 [2] CRAN (R 4.5.0) Formula 1.2-5 2023-02-24 [2] CRAN (R 4.5.0) furrr 0.3.1 2022-08-15 [2] CRAN (R 4.5.0) future 1.67.0 2025-07-29 [2] CRAN (R 4.5.0) generics 0.1.4 2025-05-09 [2] CRAN (R 4.5.0) ggforce * 0.5.0 2025-06-18 [1] CRAN (R 4.5.0) ggplot2 * 4.0.0 2025-09-11 [2] CRAN (R 4.5.0) ggrepel 0.9.6 2024-09-07 [2] CRAN (R 4.5.0) globals 0.18.0 2025-05-08 [2] CRAN (R 4.5.0) glue 1.8.0 2024-09-30 [2] CRAN (R 4.5.0) gridExtra * 2.3 2017-09-09 [2] CRAN (R 4.5.0) gtable 0.3.6 2024-10-25 [2] CRAN (R 4.5.0) haven * 2.5.5 2025-05-30 [2] CRAN (R 4.5.0) hms 1.1.3 2023-03-21 [2] CRAN (R 4.5.0) htmltools 0.5.8.1 2024-04-04 [2] CRAN (R 4.5.0) huxtable * 5.7.0 2025-08-18 [2] CRAN (R 4.5.0) igraph * 2.1.4 2025-01-23 [2] CRAN (R 4.5.0) insight 1.4.2 2025-09-02 [2] CRAN (R 4.5.0) jquerylib 0.1.4 2021-04-26 [2] CRAN (R 4.5.0) jsonlite 2.0.0 2025-03-27 [2] CRAN (R 4.5.0) jtools * 2.3.0 2024-08-25 [2] CRAN (R 4.5.0) knitr * 1.50 2025-03-16 [2] CRAN (R 4.5.0) labeling 0.4.3 2023-08-29 [2] CRAN (R 4.5.0) lattice 0.22-7 2025-04-02 [2] CRAN (R 4.5.1) leaps * 3.2 2024-06-10 [2] CRAN (R 4.5.0) lifecycle 1.0.4 2023-11-07 [2] CRAN (R 4.5.0) listenv 0.9.1 2024-01-29 [2] CRAN (R 4.5.0) lmtest * 0.9-40 2022-03-21 [2] CRAN (R 4.5.0) lubridate * 1.9.4 2024-12-08 [2] CRAN (R 4.5.0) magrittr 2.0.4 2025-09-12 [2] CRAN (R 4.5.0) MASS * 7.3-65 2025-02-28 [2] CRAN (R 4.5.1) Matrix * 1.7-3 2025-03-11 [2] CRAN (R 4.5.1) mitools * 2.4 2019-04-26 [1] CRAN (R 4.5.0) mnormt 2.1.1 2022-09-26 [2] CRAN (R 4.5.0) modelsummary * 2.5.0 2025-08-25 [2] CRAN (R 4.5.0) mvtnorm 1.3-3 2025-01-10 [2] CRAN (R 4.5.0) nlme 3.1-168 2025-03-31 [2] CRAN (R 4.5.1) pander 0.6.6 2025-03-01 [2] CRAN (R 4.5.0) parallelly 1.45.1 2025-07-24 [2] CRAN (R 4.5.0) patchwork * 1.3.2 2025-08-25 [2] CRAN (R 4.5.0) pheatmap * 1.0.13 2025-06-05 [2] CRAN (R 4.5.0) pillar 1.11.1 2025-09-17 [2] CRAN (R 4.5.0) pkgconfig 2.0.3 2019-09-22 [2] CRAN (R 4.5.0) polyclip 1.10-7 2024-07-23 [1] CRAN (R 4.5.0) psych * 2.5.6 2025-06-23 [2] CRAN (R 4.5.0) purrr * 1.1.0 2025-07-10 [2] CRAN (R 4.5.0) R6 2.6.1 2025-02-15 [2] CRAN (R 4.5.0) ragg 1.5.0 2025-09-02 [2] CRAN (R 4.5.0) rcartocolor * 2.1.2 2025-07-23 [2] CRAN (R 4.5.0) RColorBrewer * 1.1-3 2022-04-03 [2] CRAN (R 4.5.0) Rcpp 1.1.0 2025-07-02 [2] CRAN (R 4.5.0) readr * 2.1.5 2024-01-10 [2] CRAN (R 4.5.0) readxl * 1.4.5 2025-03-07 [2] CRAN (R 4.5.0) relaimpo * 2.2-7 2023-10-04 [1] CRAN (R 4.5.0) rlang 1.1.6 2025-04-11 [2] CRAN (R 4.5.0) rmarkdown 2.30 2025-09-28 [2] CRAN (R 4.5.0) rstudioapi 0.17.1 2024-10-22 [2] CRAN (R 4.5.0) S7 0.2.0 2024-11-07 [2] CRAN (R 4.5.0) sandwich * 3.1-1 2024-09-15 [2] CRAN (R 4.5.0) sass 0.4.10 2025-04-11 [2] CRAN (R 4.5.0) scales * 1.4.0 2025-04-24 [2] CRAN (R 4.5.0) sessioninfo 1.2.3 2025-02-05 [1] CRAN (R 4.5.0) stargazer * 5.2.3 2022-03-04 [2] CRAN (R 4.5.0) stringi 1.8.7 2025-03-27 [2] CRAN (R 4.5.0) stringr * 1.5.2 2025-09-08 [2] CRAN (R 4.5.0) survey * 4.4-8 2025-08-28 [1] CRAN (R 4.5.0) survival * 3.8-3 2024-12-17 [2] CRAN (R 4.5.1) systemfonts 1.2.3 2025-04-30 [2] CRAN (R 4.5.0) tables 0.9.31 2024-08-29 [2] CRAN (R 4.5.0) textshaping 1.0.3 2025-09-02 [2] CRAN (R 4.5.0) tibble * 3.3.0 2025-06-08 [2] CRAN (R 4.5.0) tidyr * 1.3.1 2024-01-24 [2] CRAN (R 4.5.0) tidyselect 1.2.1 2024-03-11 [2] CRAN (R 4.5.0) tidyverse * 2.0.0 2023-02-22 [2] CRAN (R 4.5.0) timechange 0.3.0 2024-01-18 [2] CRAN (R 4.5.0) tinytable 0.13.0 2025-08-19 [2] CRAN (R 4.5.0) tweenr 2.0.3 2024-02-26 [1] CRAN (R 4.5.0) tzdb 0.5.0 2025-03-15 [2] CRAN (R 4.5.0) vctrs 0.6.5 2023-12-01 [2] CRAN (R 4.5.0) viridis * 0.6.5 2024-01-29 [2] CRAN (R 4.5.0) viridisLite * 0.4.2 2023-05-02 [2] CRAN (R 4.5.0) vroom 1.6.6 2025-09-19 [2] CRAN (R 4.5.0) withr 3.0.2 2024-10-28 [2] CRAN (R 4.5.0) writexl * 1.5.4 2025-04-15 [2] CRAN (R 4.5.0) xfun 0.53 2025-08-19 [2] CRAN (R 4.5.0) yaml 2.3.10 2024-07-26 [2] CRAN (R 4.5.0) zoo * 1.8-14 2025-04-10 [2] CRAN (R 4.5.0)

[1] /Users/jlabar/Library/R/arm64/4.5/library [2] /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/library * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────