Supporting Information

Anatomical network analysis shows decoupling of modular lability and complexity in the evolution of the primate skull

Borja Esteve-Altava, Julia C. Boughner, Rui Diogo, Brian A. Villmoare, and Diego Rasskin-Gutman

Data location: (

Description: Protocol of the anatomical network analysis performed to analyze modularity and complexity in the 20 skull network models sudied.

0. Content
  1. Pre-processing skull networks
  2. Identifying connectivity modules in skull networks
  3. Quantifying the modularity and complexity using network parameters
  4. Estimating the phylogenetic signal of network parameters
  5. Testing the Near-decomposability Hypothesis
1. Pre-processing skull networks

We load the raw adjacency matrices from the repository and convert them into igraph objects.

  # load data
mat.list <- mapply(read.xls, xls = "primateAdjm.xls", sheet=1:20)
species <- c("Aotus", "Callithrix", "Cercopithecus", "Colobus", "Cynocephalus", "Gorilla", "Homo", "Hylobates", "Lemur", "Loris", "Macaca", "Nycticebus", "Pan", "Papio", "Pithecia", "Pongo", "Propithecus", "Saimiri", "Tarsius", "Tupaia")
parameter.names <- c("Bones (N)", "Interactions (K)", "Compactness (D)", "Redundancy (C)", "Disparity (H)", "Modularity (M)")
names(mat.list) <- species
  # create adjacency matrices
adj.list <- lapply(mat.list, data.matrix, rownames.force = TRUE)
  # create igraph objects
graph.list <- lapply(adj.list, graph.adjacency, mode = "undirected")
2. Identifying connectivity modules in skull networks

We identify connectivity modules using a hierarchical cluster analysis of the topological overlap matrix, which is used as the dissimilarity matrix.

  # compute topological overlap
  source("") # load GTOMmdist1()
tom.list <- lapply(adj.list, GTOMmdist1, m = 1)
  # compute hierarchical cluster analysis
dist.tom.list <- lapply(tom.list, as.dist)
hclust.list <- lapply(dist.tom.list, hclust, method = "average") # method UPGMA
for (i in 1:20){hclust.list[[i]]$labels <- V(graph.list[[i]])$name}
  # extract membership, max. q value, and number of modules (best split) 
membership.list <- list(); q.value.vector <- vector(); split.vector <- vector()
for (i in 1:20){
        nodes <- vcount(graph.list[[i]])
        q.value <- vector()
        for (j in 1:nodes){
                membership <- as.vector(cutree(hclust.list[[i]], k = j))
                q.value[j] <- modularity(graph.list[[i]], membership)
        split.vector[i] <- which(q.value == max(q.value)) # best partition
        membership.list[i] <- list(as.vector(cutree(hclust.list[[i]], k = split.vector[i])))
        q.value.vector[i] <- max(q.value)

A dendrogram summarizes the identified modules using a different color for each of the connectivity modules. Dendrograms show the hierarchical grouping of bones into modules.