This R Markdown document presents an analysis of the latent space positions of countries based on arms trade data over the years. The analysis uses the latentnet package to fit a latent space model and ggplot2 to visualize the results.
The data used for this analysis is sourced from a cleaned dataset of arms trade registers. Below is the code to load and preprocess the data:
data <- read.csv("data/arms_data/trade-register-cleaned-year-order.csv")
The following code defines a function to fit a latent space model for a given year and generate plots. This function is applied to the data for the years 2018 to 2023.
set.seed(123)
latent_model <- function(year) {
data_year <- subset(data, Year == year)
data_year$Source <- as.character(data_year$Source)
data_year$Target <- as.character(data_year$Target)
nodes <- unique(c(data_year$Source, data_year$Target))
adjacency_matrix <- matrix(0, nrow = length(nodes), ncol = length(nodes), dimnames = list(nodes, nodes))
for (i in 1:nrow(data_year)) {
source <- data_year$Source[i]
target <- data_year$Target[i]
weight <- data_year$Weight[i]
adjacency_matrix[source, target] <- weight
}
net <- as.network(adjacency_matrix, directed = FALSE)
set.edge.value(net, "weight", adjacency_matrix[adjacency_matrix != 0])
data.fit <- ergmm(net ~ edges + euclidean(d = 2, G=3), verbose = TRUE)
summary(data.fit)
latent_positions <- data.fit$mcmc.mle$Z
latent_positions_df <- data.frame(
Country = nodes,
X = latent_positions[, 1],
Y = latent_positions[, 2]
)
p <- ggplot() +
geom_point(data = latent_positions_df, aes(x = X, y = Y), color = "blue") +
geom_text(data = latent_positions_df, aes(x = X, y = Y, label = Country), vjust = -0.5, hjust = 0.5) +
ggtitle(paste("Latent Positions of Countries for Year", year)) +
xlab("Latent Dimension 1") +
ylab("Latent Dimension 2") +
theme_minimal()
print(p)
}
years <- c(2018, 2019, 2020, 2021, 2022, 2023)
for (year in years) {
latent_model(year)
}
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Warning in eval(substitute(expr), data, enclos = parent.frame()): Bad
## clustering: treating 2 clusters as empty.
## NOTE: It is not certain whether it is appropriate to use latentnet's BIC to select latent space dimension, whether or not to include actor-specific random effects, and to compare clustered models with the unclustered model.
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Warning in eval(substitute(expr), data, enclos = parent.frame()): Bad
## clustering: treating 2 clusters as empty.
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Warning in eval(substitute(expr), data, enclos = parent.frame()): Bad
## clustering: treating 2 clusters as empty.
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Backing off: too few acceptances. If you see this message several times in a row, use a longer burnin.
## Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
## Warning in eval(substitute(expr), data, enclos = parent.frame()): Bad
## clustering: treating 2 clusters as empty.
This analysis provides a visual representation of the latent space positions of countries based on arms trade data over several years. The latentnet and ggplot2 packages in R are powerful tools for such network analyses and visualizations.