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)# 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)
)#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.")| 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 |
# 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)
}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")
)| Step | Block | k added | R² | Δ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 |
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")
)| Step | Block | k added | R² | Δ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 |
# 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
)| 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 | |
# 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 plotset.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 plotresiduals1 <- residuals(model1)
residuals2 <- residuals(model2)
shapiro.test(residuals1)
shapiro.test(residuals2)
hist(residuals1)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.
## 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
## 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.
##
## studentized Breusch-Pagan test
##
## data: model1
## BP = 89.908, df = 13, p-value = 0.0000000000001455
##
## 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.
# 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
)| 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 | |
# 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# 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_setlibrary(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')."
)| 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 ─────────────────────────────────────────────────────────────── 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.
──────────────────────────────────────────────────────────────────────────────