library(haven)
library(psych)
library(GPArotation)
library(dplyr)
library(tidyr)
library(forcats)
library(corrplot)
library(ggplot2)
library(knitr)
library(kableExtra)
library(kirkegaard)

figs_dir <- "figs"
dir.create(figs_dir, showWarnings = FALSE)

Data

lew_data <- read_sav("Lewandowsky.sav")

# 14 conspiracy items (1–4 scale: strongly disagree to strongly agree)
cy_items <- c(
  "CYNewWorldOrder", "CYSARS", "CYPearlHarbor", "CYAIDS",
  "CYMLK", "CYMoon", "CYJFK", "CY911",
  "CYDiana", "CYOkla", "CYCoke", "CYArea51",
  "CYRoswell", "CYClimChange"
)

cy_labels <- c(
  "New World Order", "SARS", "Pearl Harbor", "AIDS",
  "MLK", "Moon landing", "JFK", "9/11",
  "Diana", "Oklahoma City", "Coca-Cola", "Area 51",
  "Roswell", "Climate change"
)

fa_data <- lew_data %>% select(all_of(cy_items)) %>% na.omit()

Questionnaire items

Item wordings are from Table 1 of Lewandowsky et al. (2012). All items used a 4-point scale from strongly disagree (1) to strongly agree (4).

item_wordings <- tibble::tibble(
  Variable = cy_items,
  Label = cy_labels,
  Item = c(
    "A powerful and secretive group known as the New World Order is planning to eventually rule the world through an autonomous world government that would replace sovereign governments.",
    "SARS (Severe Acute Respiratory Syndrome) was produced under laboratory conditions as a biological weapon.",
    "The U.S. government had foreknowledge about the Japanese attack on Pearl Harbor but allowed the attack to take place so as to be able to enter the Second World War.",
    "U.S. agencies intentionally created the AIDS epidemic and administered it to Black and gay men in the 1970s.",
    "The assassination of Martin Luther King Jr. was the result of an organized conspiracy by U.S. government agencies such as the FBI and CIA.",
    "The Apollo moon landings never happened and were staged in a Hollywood film studio.",
    "The assassination of John F. Kennedy was not committed by the lone gunman Lee Harvey Oswald but was rather a detailed organized conspiracy to kill the president.",
    "The U.S. government allowed the 9/11 attacks to take place so that it would have an excuse to achieve foreign and domestic goals that had been determined prior to the attacks.",
    "Princess Diana's death was not an accident but rather an organized assassination by members of the British royal family who disliked her.",
    "The Oklahoma City bombers Timothy McVeigh and Terry Nichols did not act alone but rather received assistance from neo-Nazi groups.",
    "The Coca-Cola company intentionally changed to an inferior formula with the intent of driving up demand for their classic product, later reintroducing it for their financial gain.",
    "Area 51 in Nevada is a secretive military base that contains hidden alien spacecraft and/or alien bodies.",
    "In July 1947, the U.S. military recovered the wreckage of an alien spacecraft from Roswell, NM, and covered up the fact.",
    "The claim that the climate is changing due to emissions from fossil fuels is a hoax perpetrated by corrupt scientists who want to spend more taxpayer money on climate research."
  )
)

item_wordings %>%
  kable(caption = "Conspiracy belief items (Lewandowsky et al., 2012, Table 1)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = TRUE) %>%
  column_spec(3, width = "60%")
Conspiracy belief items (Lewandowsky et al., 2012, Table 1)
Variable Label Item
CYNewWorldOrder New World Order A powerful and secretive group known as the New World Order is planning to eventually rule the world through an autonomous world government that would replace sovereign governments.
CYSARS SARS SARS (Severe Acute Respiratory Syndrome) was produced under laboratory conditions as a biological weapon.
CYPearlHarbor Pearl Harbor The U.S. government had foreknowledge about the Japanese attack on Pearl Harbor but allowed the attack to take place so as to be able to enter the Second World War.
CYAIDS AIDS U.S. agencies intentionally created the AIDS epidemic and administered it to Black and gay men in the 1970s.
CYMLK MLK The assassination of Martin Luther King Jr. was the result of an organized conspiracy by U.S. government agencies such as the FBI and CIA.
CYMoon Moon landing The Apollo moon landings never happened and were staged in a Hollywood film studio.
CYJFK JFK The assassination of John F. Kennedy was not committed by the lone gunman Lee Harvey Oswald but was rather a detailed organized conspiracy to kill the president.
CY911 9/11 The U.S. government allowed the 9/11 attacks to take place so that it would have an excuse to achieve foreign and domestic goals that had been determined prior to the attacks.
CYDiana Diana Princess Diana’s death was not an accident but rather an organized assassination by members of the British royal family who disliked her.
CYOkla Oklahoma City The Oklahoma City bombers Timothy McVeigh and Terry Nichols did not act alone but rather received assistance from neo-Nazi groups.
CYCoke Coca-Cola The Coca-Cola company intentionally changed to an inferior formula with the intent of driving up demand for their classic product, later reintroducing it for their financial gain.
CYArea51 Area 51 Area 51 in Nevada is a secretive military base that contains hidden alien spacecraft and/or alien bodies.
CYRoswell Roswell In July 1947, the U.S. military recovered the wreckage of an alien spacecraft from Roswell, NM, and covered up the fact.
CYClimChange Climate change The claim that the climate is changing due to emissions from fossil fuels is a hoax perpetrated by corrupt scientists who want to spend more taxpayer money on climate research.

Response distributions

Most items are heavily skewed toward 1 (disagree). The 1–4 ordinal scale warrants polychoric (latent) correlations.

dist_data <- fa_data %>%
  pivot_longer(everything(), names_to = "item", values_to = "response") %>%
  mutate(item = factor(item, levels = cy_items, labels = cy_labels)) %>%
  group_by(item, response) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(item) %>%
  mutate(pct = n / sum(n)) %>%
  ungroup() %>%
  # Order items by mean response (i.e., endorsement)
  left_join(
    fa_data %>%
      pivot_longer(everything(), names_to = "item", values_to = "response") %>%
      mutate(item = factor(item, levels = cy_items, labels = cy_labels)) %>%
      group_by(item) %>%
      summarise(mean_resp = mean(response), .groups = "drop"),
    by = "item"
  ) %>%
  mutate(
    item = fct_reorder(item, mean_resp),
    response = factor(response, levels = 1:4,
      labels = c("Strongly disagree", "Disagree", "Agree", "Strongly agree"))
  )

ggplot(dist_data, aes(x = item, y = pct, fill = response)) +
  geom_bar(stat = "identity") +
  geom_text(
    aes(label = ifelse(pct >= 0.04, paste0(round(pct * 100), "%"), "")),
    position = position_stack(vjust = 0.5), size = 3
  ) +
  coord_flip() +
  scale_y_continuous("Percentage", labels = scales::percent) +
  scale_fill_brewer(palette = "Paired", name = "Response") +
  labs(x = NULL, title = "Response distributions (ordered by mean endorsement)") +
  theme_bw()

GG_save(file.path(figs_dir, "distributions.png"))

Correlation matrix (polychoric)

Because the items are ordinal (4-point scale), we use polychoric correlations to estimate the latent correlations.

poly <- polychoric(fa_data)
R_poly <- poly$rho
colnames(R_poly) <- rownames(R_poly) <- cy_labels
corrplot(
  R_poly,
  method = "color",
  type = "lower",
  addCoef.col = "black",
  number.cex = 0.6,
  tl.cex = 0.8,
  tl.col = "black",
  col = colorRampPalette(c("#2166AC", "white", "#B2182B"))(200),
  title = "Polychoric correlation matrix of conspiracy items",
  mar = c(0, 0, 2, 0)
)

png(file.path(figs_dir, "corrplot.png"), width = 9, height = 9, units = "in", res = 300)
corrplot(
  R_poly, method = "color", type = "lower", addCoef.col = "black",
  number.cex = 0.6, tl.cex = 0.8, tl.col = "black",
  col = colorRampPalette(c("#2166AC", "white", "#B2182B"))(200),
  title = "Polychoric correlation matrix of conspiracy items",
  mar = c(0, 0, 2, 0)
)
invisible(dev.off())

The correlation matrix shows a near-positive manifold: almost all inter-item correlations are positive, suggesting a general conspiracy-belief factor accounts for the bulk of shared variance. However, the magnitudes vary considerably — some items (e.g., Moon landing, AIDS) correlate weakly with others.

Determining the number of factors

fa.parallel(
  R_poly, n.obs = nrow(fa_data), fa = "both", fm = "pa",
  main = "Parallel analysis scree plot (polychoric)"
)

## Parallel analysis suggests that the number of factors =  5  and the number of components =  2
png(file.path(figs_dir, "scree.png"), width = 7, height = 5, units = "in", res = 300)
fa.parallel(R_poly, n.obs = nrow(fa_data), fa = "both", fm = "pa",
  main = "Parallel analysis scree plot (polychoric)")
## Parallel analysis suggests that the number of factors =  5  and the number of components =  2
invisible(dev.off())

The scree plot shows a dominant first eigenvalue with a sharp drop-off, consistent with a strong general factor. The second eigenvalue is near the parallel analysis threshold, making the case for a second factor marginal.

Factor analyses

We compare extraction methods on the polychoric correlation matrix. Both 1-factor and 2-factor solutions are examined, since the scree plot indicates the variance is dominated by a general factor.

print_loadings <- function(fa_obj, title) {
  ld <- as.data.frame(unclass(fa_obj$loadings))
  ld$Item <- cy_labels[match(rownames(ld), cy_items)]
  if (is.null(ld$Item)) ld$Item <- rownames(ld)
  ld$h2 <- fa_obj$communalities
  ld %>%
    select(Item, everything()) %>%
    kable(digits = 3, caption = title) %>%
    kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
}

eigen_vals <- eigen(R_poly)$values
n_kaiser <- sum(eigen_vals > 1)

1-factor models

PAF — 1 factor

fa_paf_1 <- fa(
  r = R_poly, n.obs = nrow(fa_data),
  nfactors = 1, fm = "pa"
)
print(fa_paf_1, cut = 0.2, sort = TRUE)
## Factor Analysis using method =  pa
## Call: fa(r = R_poly, nfactors = 1, n.obs = nrow(fa_data), fm = "pa")
## Standardized loadings (pattern matrix) based upon correlation matrix
##                  V  PA1    h2   u2 com
## AIDS             4 0.87 0.759 0.24   1
## Diana            9 0.82 0.665 0.33   1
## Moon landing     6 0.80 0.638 0.36   1
## 9/11             8 0.79 0.629 0.37   1
## Roswell         13 0.78 0.604 0.40   1
## Area 51         12 0.77 0.588 0.41   1
## SARS             2 0.74 0.554 0.45   1
## MLK              5 0.74 0.548 0.45   1
## JFK              7 0.71 0.507 0.49   1
## New World Order  1 0.69 0.472 0.53   1
## Pearl Harbor     3 0.65 0.425 0.57   1
## Coca-Cola       11 0.61 0.371 0.63   1
## Oklahoma City   10 0.42 0.180 0.82   1
## Climate change  14 0.29 0.086 0.91   1
## 
##                 PA1
## SS loadings    7.03
## Proportion Var 0.50
## 
## Mean item complexity =  1
## Test of the hypothesis that 1 factor is sufficient.
## 
## df null model =  91  with the objective function =  10.62 with Chi Square =  12091.13
## df of  the model are 77  and the objective function was  2.95 
## 
## The root mean square of the residuals (RMSR) is  0.09 
## The df corrected root mean square of the residuals is  0.09 
## 
## The harmonic n.obs is  1145 with the empirical chi square  1524.3  with prob <  1.5e-267 
## The total n.obs was  1145  with Likelihood Chi Square =  3356.73  with prob <  0 
## 
## Tucker Lewis Index of factoring reliability =  0.677
## RMSEA index =  0.193  and the 90 % confidence intervals are  0.187 0.199
## BIC =  2814.41
## Fit based upon off diagonal values = 0.97
## Measures of factor score adequacy             
##                                                    PA1
## Correlation of (regression) scores with factors   0.97
## Multiple R square of scores with factors          0.95
## Minimum correlation of possible factor scores     0.90
print_loadings(fa_paf_1, "PAF — 1 factor")
PAF — 1 factor
Item PA1 h2
New World Order NA 0.687 7.025
SARS NA 0.744 7.025
Pearl Harbor NA 0.652 7.025
AIDS NA 0.871 7.025
MLK NA 0.741 7.025
Moon landing NA 0.799 7.025
JFK NA 0.712 7.025
9/11 NA 0.793 7.025
Diana NA 0.816 7.025
Oklahoma City NA 0.424 7.025
Coca-Cola NA 0.609 7.025
Area 51 NA 0.767 7.025
Roswell NA 0.777 7.025
Climate change NA 0.293 7.025

ML — 1 factor

fa_ml_1 <- fa(
  r = R_poly, n.obs = nrow(fa_data),
  nfactors = 1, fm = "ml"
)
print_loadings(fa_ml_1, "ML — 1 factor")
ML — 1 factor
Item ML1 h2
New World Order NA 0.689 0.475
SARS NA 0.751 0.564
Pearl Harbor NA 0.652 0.426
AIDS NA 0.875 0.766
MLK NA 0.741 0.549
Moon landing NA 0.814 0.662
JFK NA 0.687 0.473
9/11 NA 0.794 0.631
Diana NA 0.812 0.660
Oklahoma City NA 0.420 0.176
Coca-Cola NA 0.608 0.369
Area 51 NA 0.761 0.579
Roswell NA 0.773 0.597
Climate change NA 0.307 0.094

PCA — 1 component

pca_1 <- principal(
  R_poly, nfactors = 1,
  n.obs = nrow(fa_data)
)
print_loadings(pca_1, "PCA — 1 component")
PCA — 1 component
Item PC1
New World Order NA 0.718
SARS NA 0.768
Pearl Harbor NA 0.685
AIDS NA 0.874
MLK NA 0.765
Moon landing NA 0.814
JFK NA 0.741
9/11 NA 0.809
Diana NA 0.829
Oklahoma City NA 0.461
Coca-Cola NA 0.645
Area 51 NA 0.787
Roswell NA 0.796
Climate change NA 0.322

The 1-factor solution is broadly consistent across all three extraction methods. Loadings vary across items — some (e.g., New World Order, SARS, 9/11, Roswell) load moderately, while others (Moon landing, AIDS, Oklahoma City) load weakly, indicating they are poor indicators of a general conspiracy factor.

2-factor models (Kaiser eigenvalue > 1)

PAF — 2 factors (oblimin)

This replicates the original SPSS analysis.

fa_paf_2 <- fa(
  r = R_poly, n.obs = nrow(fa_data),
  nfactors = n_kaiser, rotate = "oblimin",
  fm = "pa", normalize = TRUE
)
print(fa_paf_2, cut = 0.2, sort = TRUE)
## Factor Analysis using method =  pa
## Call: fa(r = R_poly, nfactors = n_kaiser, n.obs = nrow(fa_data), rotate = "oblimin", 
##     fm = "pa", normalize = TRUE)
## Standardized loadings (pattern matrix) based upon correlation matrix
##                 item  PA1   PA2   h2   u2 com
## 9/11               8 0.86       0.71 0.29 1.1
## MLK                5 0.85 -0.26 0.71 0.29 1.2
## AIDS               4 0.81  0.21 0.76 0.24 1.1
## Diana              9 0.78       0.66 0.34 1.0
## JFK                7 0.75       0.54 0.46 1.0
## Moon landing       6 0.71  0.28 0.66 0.34 1.3
## Pearl Harbor       3 0.69       0.46 0.54 1.0
## Roswell           13 0.69  0.27 0.63 0.37 1.3
## SARS               2 0.69       0.56 0.44 1.1
## Area 51           12 0.69  0.26 0.61 0.39 1.3
## Coca-Cola         11 0.60       0.37 0.63 1.0
## New World Order    1 0.55  0.45 0.60 0.40 1.9
## Oklahoma City     10 0.52 -0.26 0.28 0.72 1.5
## Climate change    14       0.73 0.56 0.44 1.0
## 
##                        PA1  PA2
## SS loadings           6.77 1.34
## Proportion Var        0.48 0.10
## Cumulative Var        0.48 0.58
## Proportion Explained  0.83 0.17
## Cumulative Proportion 0.83 1.00
## 
##  With factor correlations of 
##     PA1 PA2
## PA1 1.0 0.2
## PA2 0.2 1.0
## 
## Mean item complexity =  1.2
## Test of the hypothesis that 2 factors are sufficient.
## 
## df null model =  91  with the objective function =  10.62 with Chi Square =  12091.13
## df of  the model are 64  and the objective function was  2.16 
## 
## The root mean square of the residuals (RMSR) is  0.05 
## The df corrected root mean square of the residuals is  0.06 
## 
## The harmonic n.obs is  1145 with the empirical chi square  590.75  with prob <  2.7e-86 
## The total n.obs was  1145  with Likelihood Chi Square =  2453.09  with prob <  0 
## 
## Tucker Lewis Index of factoring reliability =  0.717
## RMSEA index =  0.181  and the 90 % confidence intervals are  0.175 0.187
## BIC =  2002.33
## Fit based upon off diagonal values = 0.99
## Measures of factor score adequacy             
##                                                    PA1  PA2
## Correlation of (regression) scores with factors   0.97 0.87
## Multiple R square of scores with factors          0.95 0.75
## Minimum correlation of possible factor scores     0.89 0.50
print_loadings(fa_paf_2, "PAF with oblimin rotation — 2 factors")
PAF with oblimin rotation — 2 factors
Item PA1 PA2 h2
New World Order NA 0.553 0.446 8.119
SARS NA 0.687 0.183 8.119
Pearl Harbor NA 0.694 -0.099 8.119
AIDS NA 0.805 0.212 8.119
MLK NA 0.853 -0.264 8.119
Moon landing NA 0.711 0.279 8.119
JFK NA 0.750 -0.085 8.119
9/11 NA 0.860 -0.155 8.119
Diana NA 0.785 0.105 8.119
Oklahoma City NA 0.521 -0.257 8.119
Coca-Cola NA 0.601 0.035 8.119
Area 51 NA 0.686 0.256 8.119
Roswell NA 0.694 0.265 8.119
Climate change NA 0.064 0.734 8.119

ML — 2 factors (oblimin)

fa_ml_2 <- fa(
  r = R_poly, n.obs = nrow(fa_data),
  nfactors = n_kaiser, rotate = "oblimin",
  fm = "ml", normalize = TRUE
)
print_loadings(fa_ml_2, "ML with oblimin rotation — 2 factors")
ML with oblimin rotation — 2 factors
Item ML1 ML2 h2
New World Order NA 0.547 0.169 0.457
SARS NA 0.638 0.140 0.551
Pearl Harbor NA 0.736 -0.075 0.470
AIDS NA 0.885 0.002 0.787
MLK NA 0.925 -0.185 0.650
Moon landing NA 0.582 0.283 0.650
JFK NA 0.573 0.165 0.488
9/11 NA 0.843 -0.025 0.681
Diana NA 0.679 0.168 0.649
Oklahoma City NA 0.436 -0.002 0.189
Coca-Cola NA 0.535 0.093 0.364
Area 51 NA 0.014 0.938 0.899
Roswell NA 0.040 0.922 0.904
Climate change NA 0.075 0.255 0.098

PCA — 2 components (oblimin)

pca_2 <- principal(
  R_poly, nfactors = n_kaiser, rotate = "oblimin",
  n.obs = nrow(fa_data)
)
print_loadings(pca_2, "PCA with oblimin rotation — 2 components")
PCA with oblimin rotation — 2 components
Item TC1 TC2
New World Order NA 0.594 0.474
SARS NA 0.727 0.165
Pearl Harbor NA 0.732 -0.162
AIDS NA 0.827 0.189
MLK NA 0.849 -0.300
Moon landing NA 0.746 0.267
JFK NA 0.784 -0.149
9/11 NA 0.863 -0.184
Diana NA 0.814 0.071
Oklahoma City NA 0.589 -0.465
Coca-Cola NA 0.651 -0.010
Area 51 NA 0.727 0.239
Roswell NA 0.734 0.245
Climate change NA 0.095 0.852

The 2-factor solution is unstable across extraction methods. The second factor changes identity depending on the method: ML extracts an aliens/space factor (Area 51 and Roswell loading strongly), while PAF extracts a climate factor where only the climate change item loads heavily — a degenerate single-item factor. Items shift between factors depending on the method, and neither second factor is substantively compelling. This instability, combined with the marginal second eigenvalue and the near-positive manifold in the correlation matrix, suggests the 2-factor solution is not robust. The data are better described by a single general factor with varying item quality.

pa_result <- fa.parallel(
  R_poly, n.obs = nrow(fa_data), fa = "fa", fm = "pa",
  plot = FALSE
)
## Parallel analysis suggests that the number of factors =  5  and the number of components =  NA
n_pa <- pa_result$nfact

if (n_pa > n_kaiser) {
  fa_paf_pa <- fa(
    r = R_poly, n.obs = nrow(fa_data),
    nfactors = n_pa, rotate = "oblimin",
    fm = "pa", normalize = TRUE
  )
  print_loadings(fa_paf_pa, paste0("PAF with oblimin rotation (parallel analysis: ", n_pa, " factors)"))
}
PAF with oblimin rotation (parallel analysis: 5 factors)
Item PA1 PA3 PA4 PA2 PA5 h2
New World Order NA 0.319 0.116 0.050 0.479 0.055 9.936
SARS NA 0.155 0.145 0.390 0.195 0.209 9.936
Pearl Harbor NA 0.683 0.033 0.009 0.030 -0.063 9.936
AIDS NA 0.572 0.014 0.167 0.231 0.359 9.936
MLK NA 0.631 -0.072 0.321 -0.017 -0.056 9.936
Moon landing NA 0.201 0.319 0.220 0.156 0.332 9.936
JFK NA 0.367 0.141 0.380 0.211 -0.511 9.936
9/11 NA 0.872 0.126 -0.057 -0.117 0.053 9.936
Diana NA 0.198 0.198 0.421 0.149 0.146 9.936
Oklahoma City NA -0.011 0.033 0.580 -0.098 -0.052 9.936
Coca-Cola NA 0.126 0.131 0.374 0.082 0.113 9.936
Area 51 NA -0.009 1.049 -0.063 -0.041 -0.034 9.936
Roswell NA -0.029 0.885 0.071 0.030 -0.005 9.936
Climate change NA -0.139 0.000 -0.105 1.045 -0.030 9.936

Factor diagrams

fa.diagram(fa_paf_1, main = "PAF — 1 factor", cut = 0.2)

png(file.path(figs_dir, "diagram_1f.png"), width = 8, height = 6, units = "in", res = 300)
fa.diagram(fa_paf_1, main = "PAF — 1 factor", cut = 0.2)
invisible(dev.off())
fa.diagram(fa_paf_2, main = "PAF — 2 factors (oblimin)", cut = 0.2)

png(file.path(figs_dir, "diagram_2f.png"), width = 10, height = 6, units = "in", res = 300)
fa.diagram(fa_paf_2, main = "PAF — 2 factors (oblimin)", cut = 0.2)
invisible(dev.off())

Factor scores and correlations with external variables

We score both the 1-factor and 2-factor PAF solutions and correlate them with the external variables in the dataset: free market ideology, climate science acceptance, other science acceptance, and perceived environmental problem resolution.

Note: this dataset contains no demographic variables (age, gender, education, etc.). The “external” variables are all attitudinal scales from the same survey.

# 1-factor scores
fa_scored_1 <- fa(
  r = fa_data, nfactors = 1,
  fm = "pa", scores = "regression"
)

# 2-factor scores
fa_scored_2 <- fa(
  r = fa_data, nfactors = n_kaiser,
  rotate = "oblimin", fm = "pa",
  normalize = TRUE, scores = "regression"
)

scores_1f <- as.data.frame(fa_scored_1$scores)
names(scores_1f) <- "General_conspiracy"

scores_2f <- as.data.frame(fa_scored_2$scores)
names(scores_2f) <- paste0("Factor", 1:n_kaiser)

# Bind factor scores to the complete-case rows
scored_data <- lew_data %>%
  select(all_of(cy_items)) %>%
  mutate(.row = row_number()) %>%
  na.omit()

full_scored <- lew_data[scored_data$.row, ] %>%
  bind_cols(scores_1f) %>%
  bind_cols(scores_2f)
# Define external variable groups
ext_flat <- c(
  "FreeMarket",
  "FMUnresBest", "FMNotEnvQual", "FMLimitSocial",
  "FMMoreImp", "FMThreatEnv", "FMUnsustain",
  "AcceptClimSci",
  "CO2TempUp", "CO2AtmosUp", "CO2WillNegChange", "CO2HasNegChange",
  "CauseHIV", "CauseSmoke", "CauseCO2",
  "ConsensHIV", "ConsensSmoke", "ConsensCO2",
  "CFCNowOK", "AcidRainNowOK"
)

factor_names <- c("General_conspiracy", paste0("Factor", 1:n_kaiser))
cor_mat <- cor(
  full_scored[, factor_names],
  full_scored[, ext_flat],
  use = "pairwise.complete.obs"
)

as.data.frame(t(round(cor_mat, 3))) %>%
  mutate(Variable = rownames(.)) %>%
  select(Variable, everything()) %>%
  kable(digits = 3, caption = "Correlations: factor scores with external variables") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE)
Correlations: factor scores with external variables
Variable General_conspiracy Factor1 Factor2
FreeMarket FreeMarket 0.036 -0.095 0.256
FMUnresBest FMUnresBest 0.013 -0.104 0.213
FMNotEnvQual FMNotEnvQual 0.109 0.097 0.102
FMLimitSocial FMLimitSocial 0.028 -0.055 0.165
FMMoreImp FMMoreImp 0.038 -0.067 0.211
FMThreatEnv FMThreatEnv 0.026 -0.090 0.221
FMUnsustain FMUnsustain 0.043 -0.071 0.231
AcceptClimSci AcceptClimSci -0.157 -0.011 -0.371
CO2TempUp CO2TempUp -0.172 -0.039 -0.359
CO2AtmosUp CO2AtmosUp -0.171 -0.029 -0.373
CO2WillNegChange CO2WillNegChange -0.145 0.000 -0.360
CO2HasNegChange CO2HasNegChange -0.107 0.019 -0.301
CauseHIV CauseHIV -0.338 -0.266 -0.370
CauseSmoke CauseSmoke -0.292 -0.197 -0.379
CauseCO2 CauseCO2 -0.216 -0.063 -0.426
ConsensHIV ConsensHIV -0.147 -0.104 -0.185
ConsensSmoke ConsensSmoke -0.087 -0.044 -0.141
ConsensCO2 ConsensCO2 -0.199 -0.071 -0.371
CFCNowOK CFCNowOK 0.050 -0.008 0.133
AcidRainNowOK AcidRainNowOK 0.047 -0.015 0.138
cor_long <- as.data.frame(t(cor_mat)) %>%
  mutate(Variable = rownames(.)) %>%
  pivot_longer(-Variable, names_to = "Factor", values_to = "r") %>%
  mutate(
    Factor = factor(Factor, levels = factor_names),
    Variable = factor(Variable, levels = rev(ext_flat))
  )

ggplot(cor_long, aes(x = Factor, y = Variable, fill = r)) +
  geom_tile(color = "white") +
  geom_text(aes(label = sprintf("%.2f", r)), size = 3.2) +
  scale_fill_gradient2(
    low = "#2166AC", mid = "white", high = "#B2182B",
    limits = c(-1, 1)
  ) +
  labs(
    title = "Factor score correlations with external variables",
    fill = "r"
  ) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 9))

GG_save(file.path(figs_dir, "cor_heatmap.png"))

Summary

  • Items: 14 conspiracy belief items measured on a 1–4 scale, heavily skewed toward disagreement (floor effects throughout).
  • Polychoric correlations were used because the items are ordinal. The correlation matrix shows a near-positive manifold, consistent with a general conspiracy-belief factor.
  • The scree plot shows a dominant first eigenvalue; the second is marginal.
  • 1-factor models (PAF, ML, PCA) produce consistent loading patterns. Item quality varies — some items are poor indicators of the general factor.
  • 2-factor models are unstable across extraction methods: PAF and ML yield substantially different loading patterns for the same data, indicating the second factor is not robust.
  • Factor scores from both solutions were correlated with free market ideology, climate science acceptance, science cause/consensus beliefs, and environmental problem resolution.