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: figshare.com/s/1cc7039aba8311e4ba3006ec4b8d1f61 (http://dx.doi.org/10.6084/m9.figshare.1221540)
Description: Protocol of the anatomical network
analysis performed to analyze modularity and complexity in the 20 skull
network models sudied.
0. Content
- Pre-processing skull networks
- Identifying connectivity modules in skull networks
- Quantifying the modularity and complexity using network parameters
- Estimating the phylogenetic signal of network parameters
- 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.
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
adj.list <- lapply(mat.list, data.matrix, rownames.force = TRUE)
graph.list <- lapply(adj.list, graph.adjacency, mode = "undirected")
3. Quantifying the modularity and complexity using network parameters
We quantify the modularity of skull networks (M) as the product of
the number of modules and the quality of the partition (estimated as the
max. Q value).
We quantify the complexity of each skull network using the following
network parameters: - Number of nodes (N): a proxy for the number of
bones - Number of links (K): a proxy for the number of interactions -
Density of connections (D): a proxy for skull compactness - Clustering
coefficient (C): a proxy for bone contacts redundancy - Heterogeneity of
connections (H): a proxy for skull bones disparity or diversity
net.complexity = matrix(0, ncol = 6, nrow = 20)
colnames(net.complexity) <- parameter.names
rownames(net.complexity) <- species
for (i in 1:20){
net.complexity[i,1] <- vcount(graph.list[[i]])
net.complexity[i,2] <- ecount(graph.list[[i]])
net.complexity[i,3] <- graph.density(graph.list[[i]])
net.complexity[i,4] <- transitivity(graph.list[[i]], type="average", isolates="zero")
net.complexity[i,5] <- sqrt(var(degree(graph.list[[i]])))/mean(degree(graph.list[[i]]))
net.complexity[i,6] <- split.vector[i]*q.value.vector[i]
}
print(net.complexity)
## Bones (N) Interactions (K) Compactness (D) Redundancy (C) Disparity (H) Modularity (M)
## Aotus 23 63 0.2490119 0.4889014 0.4918714 1.4814815
## Callithrix 23 63 0.2490119 0.4841082 0.5129733 0.9988662
## Cercopithecus 23 62 0.2450593 0.4900469 0.5696146 0.8939906
## Colobus 23 67 0.2648221 0.6018445 0.5114082 0.9118957
## Cynocephalus 24 68 0.2463768 0.5426467 0.4673804 1.2214533
## Gorilla 23 64 0.2529644 0.5610496 0.5358569 1.2504883
## Homo 21 64 0.3047619 0.6338661 0.4946553 0.5485840
## Hylobates 23 69 0.2727273 0.5764236 0.4846117 0.9770006
## Lemur 24 62 0.2246377 0.3588624 0.4625015 1.4418574
## Loris 24 68 0.2463768 0.5226070 0.4927639 0.8690528
## Macaca 23 61 0.2411067 0.4611833 0.5345437 0.9703037
## Nycticebus 24 68 0.2463768 0.5226070 0.4927639 0.8690528
## Pan 23 60 0.2371542 0.6140266 0.6688553 1.0216667
## Papio 23 65 0.2569170 0.6169524 0.5660752 0.9418935
## Pithecia 23 61 0.2411067 0.5581561 0.4770515 1.3657619
## Pongo 23 60 0.2371542 0.4504611 0.5263511 1.2605556
## Propithecus 24 60 0.2173913 0.3704365 0.5004346 1.6368056
## Saimiri 23 62 0.2450593 0.5222637 0.5696146 0.9677419
## Tarsius 23 65 0.2569170 0.6026613 0.5481987 0.9859172
## Tupaia 24 74 0.2681159 0.5534618 0.4627998 0.5858291
summary(net.complexity)
## Bones (N) Interactions (K) Compactness (D) Redundancy (C) Disparity (H) Modularity (M)
## Min. :21.0 Min. :60.00 Min. :0.2174 Min. :0.3589 Min. :0.4625 Min. :0.5486
## 1st Qu.:23.0 1st Qu.:61.75 1st Qu.:0.2411 1st Qu.:0.4877 1st Qu.:0.4901 1st Qu.:0.9074
## Median :23.0 Median :63.50 Median :0.2464 Median :0.5326 Median :0.5059 Median :0.9815
## Mean :23.2 Mean :64.30 Mean :0.2502 Mean :0.5266 Mean :0.5185 Mean :1.0600
## 3rd Qu.:24.0 3rd Qu.:67.25 3rd Qu.:0.2569 3rd Qu.:0.5828 3rd Qu.:0.5389 3rd Qu.:1.2530
## Max. :24.0 Max. :74.00 Max. :0.3048 Max. :0.6339 Max. :0.6689 Max. :1.6368
4. Estimating the phylogenetic signal of network parameters
We test the assumption of phylogenetic independence (Ho) of network
parameters measuring modularity (M) and complexity (N, K, D, C, H) of
skull networks using a calibrated phylogeny of Primates.
We perform both Abouheif test and Blomberg test.
If p-value < 0.05 we reject Ho (= there is a phylogenetic signal in that trait).
tree <- read.tree("primatetree.txt")
plot(tree)
traits.in.tree <- phylo4d(tree, net.complexity)
abouheif <- abouheif.moran(traits.in.tree, method = "oriAbouheif", nrepet = 1000, alter = "two-sided")
abouheif$names <- parameter.names
print(abouheif)
## class: krandtest
## Monte-Carlo tests
## Call: as.krandtest(sim = matrix(res$result, ncol = nvar, byrow = TRUE),
## obs = res$obs, alter = alter, names = test.names)
##
## Number of tests: 6
##
## Adjustment method for multiple comparisons: none
## Permutation number: 1000
## Test Obs Std.Obs Alter Pvalue
## 1 Bones (N) 0.46756114 3.4855316 two-sided 0.001998002
## 2 Interactions (K) 0.30998522 2.4520333 two-sided 0.017982018
## 3 Compactness (D) 0.03036873 0.2295683 two-sided 0.799200799
## 4 Redundancy (C) 0.24583775 1.7416025 two-sided 0.077922078
## 5 Disparity (H) 0.10497538 0.8630162 two-sided 0.390609391
## 6 Modularity (M) 0.17575027 1.3437183 two-sided 0.158841159
##
## other elements: adj.method call
plot(abouheif)
blomberg <- matrix(0, ncol = 4, nrow = 6)
rownames(blomberg) <- parameter.names
colnames(blomberg) <- c("K", "Obs variance", "Exp variance", "p-value")
for (i in 1:6){
signal <- phylosignal(net.complexity[,i], tree, reps = 1000)
blomberg[i,] <- as.numeric(signal[1:4])
}
print(blomberg)
## K Obs variance Exp variance p-value
## Bones (N) 0.4786070 2.055676e-02 2.525063e-02 0.37162837
## Interactions (K) 0.6948346 3.858027e-01 7.115512e-01 0.03996004
## Compactness (D) 0.1961156 2.340261e-05 1.757856e-05 0.83116883
## Redundancy (C) 0.3745160 2.150931e-04 2.998424e-04 0.14785215
## Disparity (H) 0.2558823 1.661558e-04 1.273957e-04 0.78221778
## Modularity (M) 0.3406290 3.127194e-03 4.057153e-03 0.17682318
5. Testing the Near-decomposability Hypothesis
According to Simon’s hypothesis, modularity facilitates the emergence
of complexity; thus, modularity and complexity should be positively
correlated.
We test the Ho: modularity~complexity r = 0, against the Ha: modularity~complexity r > 0.
If p-value < 0.05, we reject Ho (i.e. there is a near-decomposability effect).
PIC <- vector("list", 6)
names(PIC)<- parameter.names
for (i in 1:6){
PIC[[i]] <- pic(net.complexity[,i], tree)
}
cor.MN <- cor.test(PIC$Modularity, PIC$Bones, alternative = "g", method = "p")
cor.MK <- cor.test(PIC$Modularity, PIC$Interactions, alternative = "g", method = "p")
cor.MD <- cor.test(PIC$Modularity, PIC$Compactness, alternative = "g", method = "p")
cor.MC <- cor.test(PIC$Modularity, PIC$Redundancy, alternative = "g", method = "p")
cor.MH <- cor.test(PIC$Modularity, PIC$Disparity, alternative = "g", method = "p")
## r p-value CI<95% CI>95%
## N vs. M 0.6908061 0.0005288043 0.4122199 1
## K vs. M -0.4416633 0.9708311563 -0.7091683 1
## D vs. M -0.7011651 0.9995881661 -0.8566985 1
## C vs. M -0.4096686 0.9592344907 -0.6891979 1
## H vs. M 0.1490309 0.2712869847 -0.2552907 1
Results indicate that modularity and complexity might show an inverse relationship.
We test now the Ho against this alternative hypothesis, Ha: modularity~complexity r < 0.
## r p-value CI<95% CI>95%
## N vs. M 0.6908061 0.9994711957 -1 0.85125958
## K vs. M -0.4416633 0.0291688437 -1 -0.06299832
## D vs. M -0.7011651 0.0004118339 -1 -0.42875914
## C vs. M -0.4096686 0.0407655093 -1 -0.02399488
## H vs. M 0.1490309 0.7287130153 -1 0.50898768