We now investigate the first variation of the multi-network simulation model we called Context Permeability. We first investigate the properties of different network topologies that we then use in our model. We change the network models and the number of networks in which each agent interacts. Obviously, adding more networks means adding more connections. We show that what is important is not exactly the number of connections but rather the properties the networks display when they are merged.
Load the dependencies for this report.
source("../R/experiment_utils.R")
## Loading required package: ggplot2
source("../R/network.utils.R")
library(stargazer)
##
## Please cite as:
##
## Hlavac, Marek (2014). stargazer: LaTeX code and ASCII text for well-formatted regression and summary statistics tables.
## R package version 5.0. http://CRAN.R-project.org/package=stargazer
library(reshape2)
library(ggplot2)
library(bigmemory)
## Loading required package: bigmemory.sri
## Loading required package: BH
##
## bigmemory >= 4.0 is a major revision since 3.1.2; please see packages
## biganalytics and and bigtabulate and http://www.bigmemory.org for more information.
library(parallel)
#to create a progress bar
library(BBmisc)
We first investigate the properties of regular networks. We use a K-Regular network model in which each node has the same number of connections. The number of connections is controlled by parameter k. Each agent has _2*k_ connections. This structure is not very realistic if we compare it with real network structures. Nonetheless, this investigation is useful for two reasons. The first is that we can investigate the influence of connectivity in the convergence to consensus. The second is that these models of interaction can be used outside the social simulation domain, nothing prohibits multi-agent systems to use these as models of interaction, we might even want to construct highly clustered networks of agents. Given this, it is valuable to know how the system responds to such structures.
Each network is generated by placing the nodes in a ring and connecting each node to its next k-neighbours. The initial order of the nodes in the ring is randomised so that we can have multiple instances of k-regular networks in which agents have different neighbourhoods.
We generate multiple k-regular networks and agents are allowed to interact in any one of them. The number of nodes is the same in all the networks. Given that the networks are randomised, neighbourshoods may or may not overlap. What this means is that adding more regular networks is not the same as creating a k-regular network with twice the number of connections. As we will see, the overlapping different k-regular networks changes the original regular properties. Overlapping regular structures can result in the creation of shortcuts between neighbourhoods that would not be created by the regular network generation model.
In a first experiment we performed experiment with k-regular networks with different k values. We also varied the number of concomitant networks as follows:
## Loading required package: data.table
| k values | 1 | 2 | 3 | 4 | 5 | 10 | 20 | 30 | 40 | 50 |
| number of networks | 1 | 2 | 3 | 4 | 5 |
used (Mb) gc trigger (Mb) max used (Mb) Ncells 538010 28.8 741108 39.6 667722 35.7 Vcells 733925 5.6 1300721 10.0 1162577 8.9
We load the network data from the regular networks experiment with the bigmemory package which is more efficient in terms of memory management.
network_data <- read.big.matrix(filename="../data/context_permeability/regular_networks/networks.csv", header=T, sep=";")
## Warning: Because type was not specified, we chose integer based on the
## first line of data.
Before a more detailed analysis lets consider an example. Lets consider the scenario where we have 2 networks with k = 10. We retrieve the networks from the first run and make some measurements.
#extract networks for num networks = 2 and k = 10 as an example
cfg <- params[params$"num.network" == 2 & params$"network.0.k" == 10,][[1]]
#use the configuration id to filter the data
network1 <- read.big.network.layer(data=network_data,cfg=cfg,run=1, layer=0)
## Loading required package: igraph
network2 <- read.big.network.layer(data=network_data,cfg=cfg,run=1, layer=1)
#combine the 2 networks
combined_network <- network1 + network2
#some measures
#clustering
network1$cc <- transitivity(network1, type=c("globalundirected"))
network2$cc <- transitivity(network2, type=c("globalundirected"))
combined_network$cc <- transitivity(combined_network, type=c("globalundirected"))
#average path length
network1$apl <- average.path.length(network1, directed=FALSE)
network2$apl <- average.path.length(network2, directed=FALSE)
combined_network$apl <- average.path.length(combined_network, directed=FALSE)
net1 <- c(length(V(network1)), length(E(network1)),network1$cc, network1$apl)
net2 <- c(length(V(network2)), length(E(network2)),network2$cc, network2$apl)
combnet <- c(length(V(combined_network)), length(E(combined_network)),combined_network$cc,combined_network$apl)
netprop.table <- as.data.frame(rbind(net1,net2,combnet))
colnames(netprop.table)<- c("Number of Nodes","Number of Edges","Clustering Coefficient", "Average Path Length")
rownames(netprop.table) <- c("K-Regular 1", "K-Regular 2", "Combined")
For this configuration we have two networks in which the agent can interact. In the next figure you can see the two k-regular networks with k = 10 followed by the network that results from merging these two structures. The networks are drawn using the Kamada-Kawai Layout which “regards the desirable”geometric" (Euclidean) distance between two vertices in the drawing as the “graph theoretic”" distance between them in the corresponding graph.
color1 <- "#7D9C9F"
color2 <- "#B1B1B1"
color_over <- "#FF003F"
E(network1)$color <- color1
E(network2)$color <- color2
el1 <- apply(get.edgelist(network1), 1, paste, collapse="-")
el2 <- apply(get.edgelist(network2), 1, paste, collapse="-")
elc <- apply(get.edgelist(combined_network), 1, paste, collapse="-")
E(combined_network)$color <- ifelse((elc %in% el1) & (elc %in% el2), color_over, ifelse((elc %in% el1), color1, color2))
plot(network1,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="10-Regular 1")
plot(network2,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="10-Regular 2")
plot(combined_network,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="Combined 10-Regulars")
#print to pdf
pdf(paste("./pdf/","network_properties_merge_2_10regular.pdf"), width=15, height=5)
par(mfrow=c(1,3))
plot(network1,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="10-Regular 1")
plot(network2,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="10-Regular 2")
plot(combined_network,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="Combined 10-Regulars")
dev.off()
pdf 2
stargazer(netprop.table, type="html", summary = FALSE)
| Number of Nodes | Number of Edges | Clustering Coefficient | Average Path Length | |
| K-Regular 1 | 100 | 1,000 | 0.711 | 2.980 |
| K-Regular 2 | 100 | 1,000 | 0.711 | 2.980 |
| Combined | 100 | 1,823 | 0.509 | 1.632 |
#clean up the mess
gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 1157397 61.9 1835812 98.1 1835812 98.1 Vcells 2029383 15.5 3361213 25.7 3124965 23.9 We can see by the results of the layout that the distance between nodes in the network has decreased, this is confirmed by the decreased average path length of the combined networks. To illustrate our previous point that this is not the same as having a k-regular network with twice the size lets retrieve the setup with 1 k-regular network with k = 20.
#now lets select a network with twice the k value
#extract networks for num networks = 2 and k = 10 as an example
cfg <- params[params$"num.network" == 1 & params$"network.0.k" == 20,][[1]]
#use the configuration id to filter the data
network_k_20 <- read.big.network.layer(data=network_data,cfg=cfg,run=1, layer=0)
#print to report
par(mfrow=c(1,1))
plot(network_k_20,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="K-Regular with K=20")
#print to pdf
pdf(paste("./pdf/","network_properties_1_20regular.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot(network_k_20,vertex.size = 2, vertex.label=NA, layout = layout.kamada.kawai, main="K-Regular with K=20")
dev.off()
pdf 2
As you can see in the following table, while the clustering coefficient of a 20-Regular network is approximately the same as the 10-Regulars, it is higher than this particular combination of regular networks, the average path length also decreases as there are more connections between the nodes.
network_k_20$cc <- transitivity(network_k_20, type=c("globalundirected"))
network_k_20$apl <- average.path.length(network_k_20, directed=FALSE)
network_k_20.props <- c(length(V(network_k_20)),
length(E(network_k_20)),
network_k_20$cc,
network_k_20$apl)
netprop.table <- as.data.frame(rbind(net1,net2,combnet,network_k_20.props))
colnames(netprop.table)<- c("Number of Nodes","Number of Edges","Clustering Coefficient", "Average Path Length")
rownames(netprop.table) <- c("10-Regular 1", "10-Regular 2", "Combined 10-Regulars", "20-Regular Network")
stargazer(netprop.table, type="html", summary = FALSE)
| Number of Nodes | Number of Edges | Clustering Coefficient | Average Path Length | |
| 10-Regular 1 | 100 | 1,000 | 0.711 | 2.980 |
| 10-Regular 2 | 100 | 1,000 | 0.711 | 2.980 |
| Combined 10-Regulars | 100 | 1,823 | 0.509 | 1.632 |
| 20-Regular Network | 100 | 2,000 | 0.731 | 1.788 |
This is not always the case, as we will show, since the nodes are subjected to random permutations to create different instances of K-Regular networks, we can have different overlaps that create different network topologies. Obviously, this is not the only difference. From a modelling perspective, different networks can display different properties as well, we can assign different tolerances or trust depending on the network the agent is interacting in.
We will now investigate, what kind of properties we can get from merging K-Regular networks. We do this empirically by taking the network instances used in the simulation and analysing the distribution of clustering coefficient and average path length for the different configurations where we consider multiple networks (from 1 to 5 in this case).
#Collect the network data and create a data table to hold the network properties
## Number of workers (R processes) to use:
numWorkers <- 8
measure_parallel <- function(cfg,r){
data <- network_data
network <- read.big.network(data,cfg,r)
properties <- measure.network(network)
properties <- cbind(r,properties)
return(properties)
}
props <- NULL
num_networks <- c(1,2,3,4,5)
k_values <- c(1:5,seq(10,50,10))
runs <- sort(unique(network_data[,"run"]))
pb <- makeProgressBar(min=0, max=(length(num_networks)*length(k_values)), label="network analysis")
#pre-alocate a matrix for the network properties
props <- matrix(nrow=(length(num_networks)*length(k_values)*length(runs)), ncol=7)
i <- 0
for(n in num_networks){
#reads the properties for all the k-regular networks with the given k and num_networks
for(k in k_values){
cfg <- params[params$"num.network" == n & params$"network.0.k" == k,][[1]]
properties <- mcmapply(cfg=cfg, r=runs, measure_parallel, mc.cores = numWorkers)
properties <- t(properties)
props[(i+1):(i+100),] <- cbind(k,n,properties)
i <- i + 100
#some progress feddback
pb$inc(1,paste("reading n=",n,"k=",k,"\n"))
gc()
}
}
pb$kill()
colnames(props)<-c("k","networks","run","nodes","edges","clustering-coefficient","average-path-length")
#clean up
rm(pb)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 589545 31.5 1835812 98.1 1835812 98.1
## Vcells 1139459 8.7 4297223 32.8 59523098 454.2
Creating boxplots to observe the average path length and the clustering coefficient, we can see that these values don’t varie much within each configuration. Within K-Regular networks we can thus assume certain property values for specific combinations of networks.
props <- as.data.frame(props)
#create average path length box plots for k = 1,2,3,4,5
net_props <- props[props$k <= 5,]
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",fill=as.factor(net_props$k)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="K", y="Average Path Length", x="Number of Networks")
#print to report
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_kreg_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#create average path length box plots for k = 10, 20,30,40,50
net_props <- props[props$k > 5,]
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",fill=as.factor(net_props$k)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="K", y="Average Path Length", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_kreg_1020304050.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#create clustering coefficient box plots for k = 1,2,3,4,5
net_props <- props[props$k <= 5,]
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",fill=as.factor(net_props$k)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="K", y="Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_kreg_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#create clustering coefficient box plots for k = 10,20,30,40,50
net_props <- props[props$k > 5,]
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",fill=as.factor(net_props$k)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="K", y="Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_kreg_1020304050.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
We now plot the average value of average path length and clustering coefficient for a total of 100 K-Regular Networks. We analyse the properties of networks with different levels of K. The number of networks refers to the number of networks in which the agents interacted at the same time. As we describe above, these are built merging the networks and suppressing the overllaping edges between nodes.
#aggregate run data by k and networks
apl_data <- melt(props, id=c("k","networks","run"),measure.vars=c("average-path-length"))
clustering_data <- melt(props, id=c("k","networks","run"),measure.vars=c("clustering-coefficient"))
average_apl_data <- dcast(apl_data, k + networks ~ variable, mean)
average_clustering_data <- dcast(clustering_data, k + networks ~ variable, mean)
#plot average path length for k = 1,2,3,4,5
net_props <- average_apl_data[average_apl_data$"k" <= 5,]
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$k), color=as.factor(net_props$k)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$k), group=as.factor(net_props$k), linetype=as.factor(net_props$k)),size=1)
plot <- plot + labs(color="K", shape="K", linetype="K", y="Average of Average Path Length", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_line_kreg_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#plot for k = 10,20,30,40,50
net_props <- average_apl_data[average_apl_data$"k" >5,]
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$k), color=as.factor(net_props$k)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$k), group=as.factor(net_props$k), linetype=as.factor(net_props$k)),size=1)
plot <- plot + labs(color="K", shape="K", linetype="K", y="Average of Average Path Length", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_line_kreg_1020304050.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#clean up
rm(apl_data,average_apl_data)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 680472 36.4 1835812 98.1 1835812 98.1
## Vcells 1383424 10.6 4297223 32.8 59523098 454.2
#plot for k = 1,2,3,4,5
net_props <- average_clustering_data[average_clustering_data$"k" <= 5, ]
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$k), color=as.factor(net_props$k)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$k), group=as.factor(net_props$k), linetype=as.factor(net_props$k)),size=1)
plot <- plot + labs(color="K", shape="K", linetype="K", y="Average of Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_line_kreg_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#plot for k = 10,20,30,40,50
net_props <- average_clustering_data[average_clustering_data$"k" > 5, ]
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$k), color=as.factor(net_props$k)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$k), group=as.factor(net_props$k), linetype=as.factor(net_props$k)),size=1)
plot <- plot + labs(color="K", shape="K", linetype="K", y="Average of Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_line_kreg_1020304050.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#clean up
rm(clustering_data,average_clustering_data,props, net_props,plot)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 680298 36.4 1835812 98.1 1835812 98.1
## Vcells 1372135 10.5 4297223 32.8 59523098 454.2
In the previous plots we can see that as we increase the number of overllaping networks, the clustering coefficient also increases. The average path lenth decreases as a result from overllapings that create shortcuts between different points in the network.
The different behaviour for k = {10,20} and k = {30,40,50} can be explained by the fact that networks are overlapped in a random fashion, as such, by overlapping networks with less connectivity makes so that our composite networks have shortcuts between different points without the end points of these shortcuts being clustered together. This obviously changes as we add increase k towards 50, which is the configuration where the networks are fully connected.
We now look at the properties we get when we merge scale-free networks with different values of D (number of edges added with preferential attachement each time a new node is added to the network).
#shows the d values explored and the number of networks
params <- read.exp.parameters("../data/context_permeability/scale-free_networks/param-space_2014-05-30_18:38:14experiment:1_.csv")
params <- params[,c("cfg.id","num.networks","network.0.d")]
#read the network data
network_data <- read.big.matrix(filename="../data/context_permeability/scale-free_networks/networks.csv", header=T, sep=";")
## Warning: Because type was not specified, we chose integer based on the
## first line of data.
#Collect the network data and create a data table to hold the network properties
## Number of workers (R processes) to use:
numWorkers <- 8
measure_parallel <- function(cfg,r){
data <- network_data
network <- read.big.network(data,cfg,r)
properties <- measure.network(network)
properties <- cbind(r,properties)
return(properties)
}
props <- NULL
num_networks <- c(1,2,3,4,5)
d_values <- c(1,2,3,4,5)
runs <- sort(unique(network_data[,"run"]))
pb <- makeProgressBar(min=0, max=(length(num_networks)*length(d_values)), label="network analysis")
#pre-alocate a matrix for the network properties
props <- matrix(nrow=(length(num_networks)*length(d_values)*length(runs)), ncol=7)
i <- 0
for(n in num_networks){
#reads the properties for all the k-regular networks with the given k and num_networks
for(d in d_values){
cfg <- params[params$"num.network" == n & params$"network.0.d" == d,][[1]]
properties <- mcmapply(cfg=cfg, r=runs, measure_parallel, mc.cores = numWorkers)
properties <- t(properties)
props[(i+1):(i+100),] <- cbind(d,n,properties)
i <- i + 100
#some progress feddback
pb$inc(1,paste("reading n=",n,"d=",d,"\n"))
gc()
}
}
pb$kill()
colnames(props)<-c("d","networks","run","nodes","edges","clustering-coefficient","average-path-length")
#clean up
rm(pb)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 653654 35.0 1835812 98.1 1835812 98.1
## Vcells 1370933 10.5 4289227 32.8 59523098 454.2
Creating boxplots to observe the average path length and the clustering coefficient, we can see that these values don’t varie much within each configuration with the exception of the configuration: d=1 networks=1. This happens because the generative process is stochastic by nature and thus depends on the preferential attachement node selection. Within scale-free networks we can thus assume certain property values for specific combinations of networks much like what happens with the k-regular networks.
props <- as.data.frame(props)
#create average path length box plots for d = 1,2,3,4,5
net_props <- props
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",fill=as.factor(net_props$d)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="D", y="Average Path Length", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_sf_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#create clustering coefficient box plots for d = 1,2,3,4,5
plot <- plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",fill=as.factor(net_props$d)) )
plot <- plot + geom_boxplot()
plot <- plot + labs(fill="D", y="Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_sf_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
We now plot the average value of average path length and clustering coefficient for a total of 100 Scale-Free Networks. We analyse the properties of networks with different levels of D.
#aggregate run data by k and networks
apl_data <- melt(props, id=c("d","networks","run"),measure.vars=c("average-path-length"))
clustering_data <- melt(props, id=c("d","networks","run"),measure.vars=c("clustering-coefficient"))
average_apl_data <- dcast(apl_data, d + networks ~ variable, mean)
average_clustering_data <- dcast(clustering_data, d + networks ~ variable, mean)
#plot average path length for d = 1,2,3,4,5
net_props <- average_apl_data
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"average-path-length",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$d), color=as.factor(net_props$d)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$d), group=as.factor(net_props$d), linetype=as.factor(net_props$d)),size=1)
plot <- plot + labs(color="D", shape="D", linetype="D", y="Average of Average Path Length", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_apl_line_sf_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#clean up
rm(apl_data,average_apl_data)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 672997 36.0 1835812 98.1 1835812 98.1
## Vcells 1527845 11.7 4289227 32.8 59523098 454.2
#plot for D = 1,2,3,4,5
net_props <- average_clustering_data
plot <- ggplot(net_props, aes(x=as.factor(net_props$networks), y=net_props$"clustering-coefficient",))
plot <- plot + geom_point(aes(shape=as.factor(net_props$d), color=as.factor(net_props$d)),size = 3.5)
plot <- plot + geom_line(aes(color=as.factor(net_props$d), group=as.factor(net_props$d), linetype=as.factor(net_props$d)),size=1)
plot <- plot + labs(color="D", shape="D", linetype="D", y="Average of Clustering Coefficient", x="Number of Networks")
plot
#print to pdf
pdf(paste("./pdf/","network_properties_cc_line_sf_12345.pdf"), width=7, height=5)
par(mfrow=c(1,1))
plot
dev.off()
## pdf
## 2
#clean up
rm(clustering_data,average_clustering_data,props, net_props,plot)
gc()
## used (Mb) gc trigger (Mb) max used (Mb)
## Ncells 672962 36.0 1835812 98.1 1835812 98.1
## Vcells 1547297 11.9 4289227 32.8 59523098 454.2