#Electronic supplementary material:
#Social network dynamics: the importance of distinguishing between heterogeneous and homogeneous changes
#Mathias Franz*, Susan C. Alberts
#Department of Biology, Duke University, Durham, NC, USA
#*Correspondence to: mf144@duke.edu
library(igraph) #load igraph package, requires that this package is installed already
# this function requires as input two square matrices that contain integer values, and an integer value that determines the number of randomizations
rand_test <- function(matrix1, matrix2, num_rand)
{
num_inds <- nrow(matrix1) #number of individuals
m <- as.vector(matrix1 + matrix2) #combined observations for all dyads
num_m1 <- sum(matrix1) #total number of observations in matrix1
m_1 <- 0*m #auxiliary vector to store randomized observations for matrix1
m_2 <- 0*m #auxiliary vector to store randomized observations for matrix2
d_diff <- rep(0, num_rand) #vector that stores recorded difference in mean degree for each randomization
cc_diff <- rep(0, num_rand) #vector that stores recorded difference in global clustering coefficient for each randomization
for (i in 1:num_rand) #iteration over all randomizations
{
h <- hist(sample(rep(1:(num_inds*num_inds), m), num_m1), breaks= 0.5 + 0:(num_inds*num_inds), plot=F) #sample observations for matrix1 from combined observations for all dyads
m_1 <- matrix(h$counts , nrow=num_inds) #generate randomized matrix1
m_2 <- m - m_1 #generate randomized matrix2
m_2 <- matrix(m_2, nrow=num_inds)
d_diff[i] <- mean(degree(graph.adjacency(m_2>0, mode = 'undirected'))) - mean(degree(graph.adjacency(m_1>0, mode = 'undirected'))) #calculate difference in mean degree
cc_diff[i] <- transitivity(graph.adjacency(m_2>0, mode = 'undirected')) - transitivity(graph.adjacency(m_1>0, mode = 'undirected')) #calculate difference in global clustering coefficient
}
ci_d_diff <- quantile(d_diff, probs = c(0.025,0.975), na.rm=T) #calculate 95% confidence intervals for difference in mean degree
ci_cc_diff <- quantile(cc_diff, probs = c(0.025,0.975), na.rm=T) #calculate 95% confidence intervals for difference in global clustering coefficient
obs_d_diff <- c(mean(degree(graph.adjacency(matrix2>0, mode = 'undirected'))) - mean(degree(graph.adjacency(matrix1>0, mode = 'undirected'))))
obs_cc_diff <- c(transitivity(graph.adjacency(matrix2>0, mode = 'undirected')) - transitivity(graph.adjacency(matrix1>0, mode = 'undirected')))
results <- data.frame('observed difference' = c(obs_d_diff, obs_cc_diff), 'lower CI limit' = c(ci_d_diff[1], ci_cc_diff[1]), 'upper CI limit' = c(ci_d_diff[2], ci_cc_diff[2]))
rownames(results) <- c('mean degree', 'global clustering coefficient')
return(results)
}
# generate test data set
baseline <- matrix(5*runif(100),nrow=10) #baseline interaction rates
diag(baseline) <- 0
m1 <- matrix(rpois(100, baseline),nrow=10) #generate 1st matrix with of number of observed interactions
m2 <- matrix(rpois(100, baseline),nrow=10) #generate 2nd matrix with of number of observed interactions
n <- 1000 #number of randomizations
# observed interaction matrices can be loaded into R by applying the function read.table()
# note: interaction matrices need to contain integer values that represent number of observed interactions
rand_test(m1, m2, n)