# Get principal component directions (eigenvectors)
pc1_direction <- pca$rotation[, 1]
pc2_direction <- pca$rotation[, 2]
# Center of the data
center_x <- mean(pca_data$x1)
center_y <- mean(pca_data$x2)
# Scale for arrows (proportional to variance explained)
scale_factor <- 2
arrow_scale1 <- scale_factor * sqrt(pca$sdev[1])
arrow_scale2 <- scale_factor * sqrt(pca$sdev[2])
# Create arrow data
arrows_df <- data.frame(
x = c(center_x, center_x),
y = c(center_y, center_y),
xend = c(center_x + arrow_scale1 * pc1_direction[1],
center_x + arrow_scale2 * pc2_direction[1]),
yend = c(center_y + arrow_scale1 * pc1_direction[2],
center_y + arrow_scale2 * pc2_direction[2]),
component = c("PC1", "PC2")
)
# Plot with PCA directions
ggplot(pca_data, aes(x = x1, y = x2)) +
geom_point(color = "navy", size = 2, alpha = 0.4) +
geom_segment(data = arrows_df,
aes(x = x, y = y, xend = xend, yend = yend, color = component),
arrow = arrow(length = unit(0.3, "cm"), type = "closed"),
linewidth = 1.5) +
scale_color_manual(values = c("PC1" = "red", "PC2" = "darkgreen")) +
labs(title = "Principal Components",
subtitle = sprintf("PC1 explains %.1f%% variance, PC2 explains %.1f%%",
100 * pca$sdev[1]^2 / sum(pca$sdev^2),
100 * pca$sdev[2]^2 / sum(pca$sdev^2)),
x = "Variable 1",
y = "Variable 2",
color = "Component") +
theme_minimal() +
theme(plot.title = element_text(face = "bold", size = 14)) +
coord_fixed(ratio = 1)
Social Class over Time
(Kozlowski, Taddy & Evans, 2019)