This script analyzes virtual team networks across three time points using Exponential Random Graph Models (ERGMs). The analysis examines how individual attributes (Big Five personality traits, demographics) influence network tie formation within teams.
Key Features:
# Load necessary library for network analysis
library(statnet) # Suite of packages for statistical network analysis
Before running this script, please ensure you have the following files in your working directory:
T1_AttributeData.csv - Individual attributes at Time
1T1_VoteMatrix.csv - Voting adjacency matrix at Time
1T2_AttributeData.csv - Individual attributes at Time
2T2_VoteMatrix.csv - Voting adjacency matrix at Time
2T3_AttributeData.csv - Individual attributes at Time
3T3_VoteMatrix.csv - Voting adjacency matrix at Time
3You can set your working directory using
setwd("your/path/here") or through RStudio’s Session
menu.
This function loads and preprocesses data for a given time point.
# Function to load and prepare network data for a specific time point
prepare_network_data <- function(n) {
# Load attribute and matrix files
attribute_file <- paste0("T", n, "_AttributeData.csv")
matrix_file <- paste0("T", n, "_VoteMatrix.csv")
attribute <- read.csv(attribute_file)
vote_matrix <- read.csv(matrix_file)
# Calculate matrix dimensions
endnum <- nrow(vote_matrix)
# Recode voting data: Convert to binary network
# Only rating 5 (strongest endorsement) becomes 1, all others become 0
vote_matrix[is.na(vote_matrix)] <- 0
vote_matrix[vote_matrix == "1"] <- 0
vote_matrix[vote_matrix == "2"] <- 0
vote_matrix[vote_matrix == "3"] <- 0
vote_matrix[vote_matrix == "4"] <- 0
vote_matrix[vote_matrix == "5"] <- 1
# Extract adjacency matrix (excluding header row/column)
network_matrix <- vote_matrix[2:endnum, 2:endnum]
network_matrix <- as.network.matrix(sapply(network_matrix, as.numeric))
# Create network object
# - directed = TRUE: votes have direction (A voting for B ≠ B voting for A)
# - loops = FALSE: people cannot vote for themselves
network_obj <- as.network(x = network_matrix,
directed = TRUE,
loops = FALSE,
matrix.type = "adjacency")
# Attach individual attributes as vertex attributes
for (i in 1:ncol(attribute)) {
set.vertex.attribute(network_obj, colnames(attribute)[i], attribute[, i])
}
return(network_obj)
}
# Function to run ERGM model with control variables
run_ergm_full <- function(network_obj, time_label) {
cat("\n========================================\n")
cat(paste("Time", time_label, "- ERGM with Controls\n"))
cat("========================================\n")
# Run ERGM with full set of predictors
ergm_model <- ergm(network_obj ~
# Structural effects
edges + # Baseline tie probability
mutual + # Reciprocity (A→B and B→A)
transitiveties + # Transitive closure (A→B→C implies A→C)
cyclicalties + # Cyclical patterns (A→B→C→A)
# Control variables (centered)
nodeicov("age.c") + # Age effect on receiving ties
nodeicov("tech.c") + # Technical skill effect
nodeicov("eng.c") + # English proficiency effect
nodeicov("self_ef.c") + # Self-efficacy effect
nodeicov("gender.c") + # Gender effect (receiver)
# Big Five personality traits (centered, receiver)
nodeicov("B5_a.c") + # Agreeableness
nodeicov("B5_c.c") + # Conscientiousness
nodeicov("B5_e.c") + # Extraversion
nodeicov("B5_o.c") + # Openness
nodeicov("B5_n.c") + # Neuroticism
# Big Five personality traits (centered, sender)
nodeocov("B5_a.c") + # Agreeableness
nodeocov("B5_c.c") + # Conscientiousness
nodeocov("B5_e.c") + # Extraversion
nodeocov("B5_o.c") + # Openness
nodeocov("B5_n.c"), # Neuroticism
# Model specifications
eval.loglik = TRUE,
constraints = ~blockdiag("team_id"), # Analyze teams separately
control = control.ergm(MCMLE.maxit = 10000))
cat("\nModel estimation complete!\n")
print(summary(ergm_model))
return(ergm_model)
}
# Function to run ERGM model without control variables
run_ergm_reduced <- function(network_obj, time_label) {
cat("\n========================================\n")
cat(paste("Time", time_label, "- ERGM without Controls\n"))
cat("========================================\n")
# Run ERGM with only structural effects and personality traits
ergm_model <- ergm(network_obj ~
# Structural effects
edges + # Baseline tie probability
mutual + # Reciprocity (A→B and B→A)
transitiveties + # Transitive closure (A→B→C implies A→C)
cyclicalties + # Cyclical patterns (A→B→C→A)
# Big Five personality traits (centered, receiver)
nodeicov("B5_a.c") + # Agreeableness
nodeicov("B5_c.c") + # Conscientiousness
nodeicov("B5_e.c") + # Extraversion
nodeicov("B5_o.c") + # Openness
nodeicov("B5_n.c") + # Neuroticism
# Big Five personality traits (centered, sender)
nodeocov("B5_a.c") + # Agreeableness
nodeocov("B5_c.c") + # Conscientiousness
nodeocov("B5_e.c") + # Extraversion
nodeocov("B5_o.c") + # Openness
nodeocov("B5_n.c"), # Neuroticism
# Model specifications
eval.loglik = TRUE,
constraints = ~blockdiag("team_id"), # Analyze teams separately
control = control.ergm(MCMLE.maxit = 10000))
cat("\nModel estimation complete!\n")
print(summary(ergm_model))
return(ergm_model)
}
Each time point is analyzed with both full and reduced models.
# Prepare Time 1 network data
t1.network <- prepare_network_data(1)
# Run ERGM with control variables for Time 1
t1.model.full <- run_ergm_full(t1.network, 1)
##
## ========================================
## Time 1 - ERGM with Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("age.c") + nodeicov("tech.c") + nodeicov("eng.c") +
## nodeicov("self_ef.c") + nodeicov("gender.c") + nodeicov("B5_a.c") +
## nodeicov("B5_c.c") + nodeicov("B5_e.c") + nodeicov("B5_o.c") +
## nodeicov("B5_n.c") + nodeocov("B5_a.c") + nodeocov("B5_c.c") +
## nodeocov("B5_e.c") + nodeocov("B5_o.c") + nodeocov("B5_n.c"),
## constraints = ~blockdiag("team_id"), eval.loglik = TRUE,
## control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.669395 0.107558 0 -15.521 < 1e-04 ***
## mutual -0.089673 0.232290 0 -0.386 0.699467
## transitiveties 1.073365 0.115442 0 9.298 < 1e-04 ***
## cyclicalties -0.365351 0.096541 0 -3.784 0.000154 ***
## nodeicov.age.c 0.008905 0.011223 0 0.793 0.427509
## nodeicov.tech.c 0.043826 0.058304 0 0.752 0.452239
## nodeicov.eng.c 0.339905 0.109381 0 3.108 0.001887 **
## nodeicov.self_ef.c 0.158277 0.104636 0 1.513 0.130371
## nodeicov.gender.c 0.375557 0.125848 0 2.984 0.002843 **
## nodeicov.B5_a.c -0.113183 0.131595 0 -0.860 0.389741
## nodeicov.B5_c.c 0.005798 0.137424 0 0.042 0.966350
## nodeicov.B5_e.c 0.174147 0.100186 0 1.738 0.082170 .
## nodeicov.B5_o.c 0.006029 0.123968 0 0.049 0.961214
## nodeicov.B5_n.c 0.157087 0.113014 0 1.390 0.164534
## nodeocov.B5_a.c 0.263125 0.120565 0 2.182 0.029077 *
## nodeocov.B5_c.c -0.232142 0.128767 0 -1.803 0.071419 .
## nodeocov.B5_e.c -0.007466 0.097938 0 -0.076 0.939230
## nodeocov.B5_o.c -0.089711 0.118843 0 -0.755 0.450327
## nodeocov.B5_n.c -0.028471 0.106729 0 -0.267 0.789656
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1409 on 1273 degrees of freedom
##
## AIC: 1447 BIC: 1545 (Smaller is better. MC Std. Err. = 0.5818)
# Run ERGM without control variables for Time 1
t1.model.reduced <- run_ergm_reduced(t1.network, 1)
##
## ========================================
## Time 1 - ERGM without Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("B5_a.c") + nodeicov("B5_c.c") +
## nodeicov("B5_e.c") + nodeicov("B5_o.c") + nodeicov("B5_n.c") +
## nodeocov("B5_a.c") + nodeocov("B5_c.c") + nodeocov("B5_e.c") +
## nodeocov("B5_o.c") + nodeocov("B5_n.c"), constraints = ~blockdiag("team_id"),
## eval.loglik = TRUE, control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.642664 0.110879 0 -14.815 < 1e-04 ***
## mutual -0.092612 0.233523 0 -0.397 0.691671
## transitiveties 1.076075 0.115265 0 9.336 < 1e-04 ***
## cyclicalties -0.357424 0.095141 0 -3.757 0.000172 ***
## nodeicov.B5_a.c 0.004165 0.123640 0 0.034 0.973128
## nodeicov.B5_c.c 0.144598 0.132438 0 1.092 0.274915
## nodeicov.B5_e.c 0.213883 0.096600 0 2.214 0.026822 *
## nodeicov.B5_o.c 0.027963 0.122254 0 0.229 0.819081
## nodeicov.B5_n.c 0.211147 0.109768 0 1.924 0.054407 .
## nodeocov.B5_a.c 0.292294 0.123013 0 2.376 0.017495 *
## nodeocov.B5_c.c -0.239938 0.131141 0 -1.830 0.067307 .
## nodeocov.B5_e.c 0.001956 0.096246 0 0.020 0.983782
## nodeocov.B5_o.c -0.111475 0.120292 0 -0.927 0.354083
## nodeocov.B5_n.c -0.022895 0.104692 0 -0.219 0.826888
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1429 on 1278 degrees of freedom
##
## AIC: 1457 BIC: 1530 (Smaller is better. MC Std. Err. = 0.7134)
# Prepare Time 2 network data
t2.network <- prepare_network_data(2)
# Run ERGM with control variables for Time 2
t2.model.full <- run_ergm_full(t2.network, 2)
##
## ========================================
## Time 2 - ERGM with Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("age.c") + nodeicov("tech.c") + nodeicov("eng.c") +
## nodeicov("self_ef.c") + nodeicov("gender.c") + nodeicov("B5_a.c") +
## nodeicov("B5_c.c") + nodeicov("B5_e.c") + nodeicov("B5_o.c") +
## nodeicov("B5_n.c") + nodeocov("B5_a.c") + nodeocov("B5_c.c") +
## nodeocov("B5_e.c") + nodeocov("B5_o.c") + nodeocov("B5_n.c"),
## constraints = ~blockdiag("team_id"), eval.loglik = TRUE,
## control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.641354 0.111739 0 -14.689 <1e-04 ***
## mutual -0.184742 0.231605 0 -0.798 0.4251
## transitiveties 1.162945 0.114327 0 10.172 <1e-04 ***
## cyclicalties -0.348292 0.087140 0 -3.997 <1e-04 ***
## nodeicov.age.c 0.009710 0.010382 0 0.935 0.3496
## nodeicov.tech.c 0.102645 0.059092 0 1.737 0.0824 .
## nodeicov.eng.c 0.229688 0.097951 0 2.345 0.0190 *
## nodeicov.self_ef.c 0.075468 0.098079 0 0.769 0.4416
## nodeicov.gender.c 0.291963 0.121520 0 2.403 0.0163 *
## nodeicov.B5_a.c -0.283977 0.128837 0 -2.204 0.0275 *
## nodeicov.B5_c.c 0.266630 0.133818 0 1.992 0.0463 *
## nodeicov.B5_e.c 0.228668 0.095357 0 2.398 0.0165 *
## nodeicov.B5_o.c 0.003181 0.124229 0 0.026 0.9796
## nodeicov.B5_n.c 0.134621 0.112971 0 1.192 0.2334
## nodeocov.B5_a.c 0.204907 0.120027 0 1.707 0.0878 .
## nodeocov.B5_c.c -0.094626 0.126723 0 -0.747 0.4552
## nodeocov.B5_e.c -0.068456 0.090733 0 -0.754 0.4506
## nodeocov.B5_o.c -0.105812 0.114665 0 -0.923 0.3561
## nodeocov.B5_n.c -0.116907 0.108461 0 -1.078 0.2811
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1443 on 1273 degrees of freedom
##
## AIC: 1481 BIC: 1579 (Smaller is better. MC Std. Err. = 0.5463)
# Run ERGM without control variables for Time 2
t2.model.reduced <- run_ergm_reduced(t2.network, 2)
##
## ========================================
## Time 2 - ERGM without Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("B5_a.c") + nodeicov("B5_c.c") +
## nodeicov("B5_e.c") + nodeicov("B5_o.c") + nodeicov("B5_n.c") +
## nodeocov("B5_a.c") + nodeocov("B5_c.c") + nodeocov("B5_e.c") +
## nodeocov("B5_o.c") + nodeocov("B5_n.c"), constraints = ~blockdiag("team_id"),
## eval.loglik = TRUE, control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.656278 0.109462 0 -15.131 < 1e-04 ***
## mutual -0.187132 0.231672 0 -0.808 0.41924
## transitiveties 1.186599 0.110260 0 10.762 < 1e-04 ***
## cyclicalties -0.344754 0.086204 0 -3.999 < 1e-04 ***
## nodeicov.B5_a.c -0.172197 0.126503 0 -1.361 0.17345
## nodeicov.B5_c.c 0.360679 0.128303 0 2.811 0.00494 **
## nodeicov.B5_e.c 0.243426 0.092492 0 2.632 0.00849 **
## nodeicov.B5_o.c -0.002519 0.117531 0 -0.021 0.98290
## nodeicov.B5_n.c 0.180333 0.108313 0 1.665 0.09593 .
## nodeocov.B5_a.c 0.233952 0.117515 0 1.991 0.04650 *
## nodeocov.B5_c.c -0.103335 0.119687 0 -0.863 0.38793
## nodeocov.B5_e.c -0.067927 0.093532 0 -0.726 0.46769
## nodeocov.B5_o.c -0.105904 0.117847 0 -0.899 0.36884
## nodeocov.B5_n.c -0.102215 0.103513 0 -0.987 0.32342
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1459 on 1278 degrees of freedom
##
## AIC: 1487 BIC: 1559 (Smaller is better. MC Std. Err. = 0.6546)
# Prepare Time 3 network data
t3.network <- prepare_network_data(3)
# Run ERGM with control variables for Time 3
t3.model.full <- run_ergm_full(t3.network, 3)
##
## ========================================
## Time 3 - ERGM with Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("age.c") + nodeicov("tech.c") + nodeicov("eng.c") +
## nodeicov("self_ef.c") + nodeicov("gender.c") + nodeicov("B5_a.c") +
## nodeicov("B5_c.c") + nodeicov("B5_e.c") + nodeicov("B5_o.c") +
## nodeicov("B5_n.c") + nodeocov("B5_a.c") + nodeocov("B5_c.c") +
## nodeocov("B5_e.c") + nodeocov("B5_o.c") + nodeocov("B5_n.c"),
## constraints = ~blockdiag("team_id"), eval.loglik = TRUE,
## control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.7014811 0.1074582 0 -15.834 < 1e-04 ***
## mutual -0.3840270 0.2510451 0 -1.530 0.126088
## transitiveties 1.1920625 0.1186028 0 10.051 < 1e-04 ***
## cyclicalties -0.3538807 0.0945406 0 -3.743 0.000182 ***
## nodeicov.age.c -0.0007457 0.0114700 0 -0.065 0.948161
## nodeicov.tech.c 0.0783091 0.0601161 0 1.303 0.192701
## nodeicov.eng.c 0.2516402 0.1009584 0 2.493 0.012684 *
## nodeicov.self_ef.c 0.0811618 0.1037539 0 0.782 0.434066
## nodeicov.gender.c 0.3163355 0.1260173 0 2.510 0.012064 *
## nodeicov.B5_a.c -0.3153922 0.1315448 0 -2.398 0.016503 *
## nodeicov.B5_c.c 0.3546105 0.1362886 0 2.602 0.009271 **
## nodeicov.B5_e.c 0.2066197 0.1012866 0 2.040 0.041355 *
## nodeicov.B5_o.c 0.0060494 0.1206428 0 0.050 0.960008
## nodeicov.B5_n.c 0.2303910 0.1163301 0 1.980 0.047648 *
## nodeocov.B5_a.c 0.3245078 0.1215940 0 2.669 0.007613 **
## nodeocov.B5_c.c -0.0663821 0.1349470 0 -0.492 0.622781
## nodeocov.B5_e.c -0.0557252 0.0944489 0 -0.590 0.555188
## nodeocov.B5_o.c -0.0516858 0.1201025 0 -0.430 0.666943
## nodeocov.B5_n.c 0.0103972 0.1092962 0 0.095 0.924212
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1375 on 1273 degrees of freedom
##
## AIC: 1413 BIC: 1511 (Smaller is better. MC Std. Err. = 0.6968)
# Run ERGM without control variables for Time 3
t3.model.reduced <- run_ergm_reduced(t3.network, 3)
##
## ========================================
## Time 3 - ERGM without Controls
## ========================================
##
## Model estimation complete!
## Call:
## ergm(formula = network_obj ~ edges + mutual + transitiveties +
## cyclicalties + nodeicov("B5_a.c") + nodeicov("B5_c.c") +
## nodeicov("B5_e.c") + nodeicov("B5_o.c") + nodeicov("B5_n.c") +
## nodeocov("B5_a.c") + nodeocov("B5_c.c") + nodeocov("B5_e.c") +
## nodeocov("B5_o.c") + nodeocov("B5_n.c"), constraints = ~blockdiag("team_id"),
## eval.loglik = TRUE, control = control.ergm(MCMLE.maxit = 10000))
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.70705 0.10963 0 -15.570 < 1e-04 ***
## mutual -0.40725 0.25337 0 -1.607 0.10798
## transitiveties 1.22031 0.11988 0 10.179 < 1e-04 ***
## cyclicalties -0.35087 0.09814 0 -3.575 0.00035 ***
## nodeicov.B5_a.c -0.19394 0.13275 0 -1.461 0.14402
## nodeicov.B5_c.c 0.44712 0.13745 0 3.253 0.00114 **
## nodeicov.B5_e.c 0.24089 0.09697 0 2.484 0.01299 *
## nodeicov.B5_o.c -0.01998 0.12103 0 -0.165 0.86889
## nodeicov.B5_n.c 0.27939 0.11674 0 2.393 0.01670 *
## nodeocov.B5_a.c 0.33847 0.12108 0 2.795 0.00518 **
## nodeocov.B5_c.c -0.06903 0.13183 0 -0.524 0.60050
## nodeocov.B5_e.c -0.05132 0.09758 0 -0.526 0.59890
## nodeocov.B5_o.c -0.07305 0.11770 0 -0.621 0.53485
## nodeocov.B5_n.c 0.02567 0.11032 0 0.233 0.81599
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 1791 on 1292 degrees of freedom
## Residual Deviance: 1389 on 1278 degrees of freedom
##
## AIC: 1417 BIC: 1490 (Smaller is better. MC Std. Err. = 0.8349)
# Document R version and package versions for reproducibility
sessionInfo()
## R version 4.5.1 (2025-06-13)
## Platform: aarch64-apple-darwin20
## Running under: macOS Tahoe 26.1
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: America/Chicago
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] statnet_2019.6 tsna_0.3.6 sna_2.8
## [4] statnet.common_4.12.0 ergm.count_4.1.3 tergm_4.2.2
## [7] networkDynamic_0.11.5 ergm_4.10.1 network_1.19.0
##
## loaded via a namespace (and not attached):
## [1] sass_0.4.10 generics_0.1.4 robustbase_0.99-6
## [4] stringi_1.8.7 lattice_0.22-7 digest_0.6.37
## [7] magrittr_2.0.4 evaluate_1.0.5 lpSolveAPI_5.5.2.0-17.14
## [10] grid_4.5.1 networkLite_1.1.0 fastmap_1.2.0
## [13] jsonlite_2.0.0 Matrix_1.7-3 rle_0.10.0
## [16] purrr_1.1.0 jquerylib_0.1.4 Rdpack_2.6.4
## [19] cli_3.6.5 rlang_1.1.6 rbibutils_2.3
## [22] cachem_1.1.0 yaml_2.3.10 tools_4.5.1
## [25] parallel_4.5.1 memoise_2.0.1 coda_0.19-4.1
## [28] dplyr_1.1.4 vctrs_0.6.5 R6_2.6.1
## [31] lifecycle_1.0.4 stringr_1.5.2 MASS_7.3-65
## [34] trust_0.1-8 pkgconfig_2.0.3 pillar_1.11.1
## [37] bslib_0.9.0 ergm.multi_0.3.0 glue_1.8.0
## [40] DEoptimR_1.1-4 xfun_0.53 tibble_3.3.0
## [43] tidyselect_1.2.1 rstudioapi_0.17.1 knitr_1.50
## [46] htmltools_0.5.8.1 nlme_3.1-168 rmarkdown_2.29
## [49] compiler_4.5.1
ERGM Terms Explained:
Variables:
Constraints:
Model Comparison:
Code Structure:
This script uses functional programming to reduce repetition: -
prepare_network_data(n): Loads and prepares data for time
point n - run_ergm_full(): Runs ERGM model with all control
variables - run_ergm_reduced(): Runs ERGM model without
control variables - Each time point is analyzed with both model types -
Models stored as t1.model.full,
t1.model.reduced, etc.