Nothing
######################################
# a wrapper for centrality measures ##
######################################
# converts a matrix to a vector
mat2vec<-function(x, diag=FALSE, tol=1e-10)
{
# Compute weights matrix:
x <- getWmat(x)
if(!is.matrix(x)) stop("A matrix is required as input")
symm<-ifelse(isSymmetric.matrix(object=unname(x), tol=tol), TRUE, FALSE) # detect whether the graph is directed
if(diag==FALSE)
{
if(symm) vec<-x[upper.tri(x)] else vec<-c(x[upper.tri(x)], x[lower.tri(x)])
} else if (diag==TRUE)
{
vec<-as.vector(x)
}
vec
}
# Exported:
centrality_auto<-function(x, weighted = TRUE, signed = TRUE)
{
# This function recognizes whether a network is weighted, directed and
# whether there are disconnected nodes.
# It computes centrality according to the matrix given as input.
# If the network is disconnected, closeness is computed only for the largest component.
# INPUT
# x = an adjacency matrix or a weights matrix
# OUTPUT
# the output depends on the network given as input.
# - if x is unweighted and directed
# then the InDegree, the OutDegree, the unweighted node betweenness,
# node closenes, and edge betweenness centralities are computed
# - if x is unweighted and undirected
# then the Degree, the unweighted node betweenness,
# node closenes, and edge betweenness centralities are computed
# - if x is weighted and directed
# then the InStrength, the OutStrength, the weighted node betweenness,
# node closenes, and edge betweenness centralities are computed
# - if x is weighted and undirected
# then the Strength, the weighted node betweenness,
# node closenes, and edge betweenness centralities are computed
# require(sna)
# require(qgraph)
# require(igraph)
# Compute weights matrix:
x <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(x))
{
return(lapply(x, centrality_auto, weighted = weighted, signed = signed))
}
# Make unweighted or unsigned:
if (!isTRUE(weighted)){
x <- sign(x)
}
if (!isTRUE(signed)){
x <- abs(x)
}
if(!is.matrix(x)) stop("the input network must be an adjacency or weights matrix")
diag(x)<-0 # loops are not included in centrality analysis
# x<-abs(x) # signs are not included in centrality analysis
directed.gr<-ifelse(isSymmetric.matrix(object=x, tol=1e-12), FALSE, TRUE) # detect whether the graph is directed
weighted.gr<-ifelse(all(mat2vec(x)%in%c(0,1)), FALSE, TRUE) # detect whether the graph is weighted
# compute centrality with package qgraph: InDegree, OutDegree, Closeness, Betwenness
net_qg<-qgraph(x, diag=FALSE, labels=colnames(x), DoNotPlot=TRUE, minimum=0)
centr<-centrality(net_qg)
# betweenness should be divided by two if the network is undirected
if(directed.gr & !weighted.gr) centr1<-data.frame(cbind("Betweenness"=centr$Betweenness, "Closeness"=centr$Closeness, "InDegree"=centr$InDegree, "OutDegree"=centr$OutDegree, "OutExpectedInfluence" = centr$OutExpectedInfluence, "InExpectedInfluence" = centr$InExpectedInfluence ))
if(directed.gr & weighted.gr) centr1<-data.frame(cbind("Betweenness"=centr$Betweenness, "Closeness"=centr$Closeness, "InStrength"=centr$InDegree, "OutStrength"=centr$OutDegree, "OutExpectedInfluence" = centr$OutExpectedInfluence, "InExpectedInfluence" = centr$InExpectedInfluence))
if(!directed.gr & !weighted.gr) centr1<-data.frame(cbind("Betweenness"=centr$Betweenness/2, "Closeness"=centr$Closeness, "Degree"=centr$OutDegree, "ExpectedInfluence" = centr$OutExpectedInfluence))
if(!directed.gr & weighted.gr) centr1<-data.frame(cbind("Betweenness"=centr$Betweenness/2, "Closeness"=centr$Closeness, "Strength"=centr$OutDegree, "ExpectedInfluence" = centr$OutExpectedInfluence))
row.names(centr1)<-colnames(x)
# if the largest component is smaller than the network, closeness is recomputed only on the largest component
log <- capture.output({
graph <- igraph::graph.adjacency(1*(x!=0), mode = ifelse(directed.gr,"directed","undirected"))
comps <- igraph::components(graph)
largcomp <- comps$membership == which.max(comps$csize)
# largcomp<-component.largest(x, connected="strong") # select only the largest component
})
if(sum(largcomp)<ncol(x) & sum(largcomp) > 1)
{
x2<-x[largcomp,largcomp]
clos<-centrality(qgraph(x2, diag=FALSE, labels=colnames(x)[largcomp], DoNotPlot=TRUE, minimum=0))$Closeness
centr1$Closeness[largcomp]<-clos
centr1$Closeness[!largcomp]<-NA
}
# # compute edge betweenness with package igraph
# net_ig_abs<-graph.adjacency(adjmatrix=abs(1/x), mode=ifelse(directed.gr, "directed", "undirected"), weighted=(if(weighted.gr)TRUE), diag=FALSE)
#
# compute edge betweenness with package igraph
if (weighted.gr){
igraphinput <- abs(1/x)
} else {
igraphinput <- x
}
net_ig_abs<- igraph::graph.adjacency(adjmatrix=igraphinput, mode=ifelse(directed.gr, "directed", "undirected"), weighted=(if(weighted.gr)TRUE), diag=FALSE)
# edge betweenness centrality
edgebet<-edge.betweenness(graph=net_ig_abs, directed=directed.gr)
el<-data.frame(get.edgelist(graph=net_ig_abs), stringsAsFactors=FALSE)
edgebet<-merge(el, edgebet, by=0)
edgebet$Row.names<-NULL
names(edgebet)<-c("from", "to", "edgebetweenness")
edgebet<-edgebet[order(edgebet$edgebetweenness, decreasing=TRUE),]
# shortest path lengths
ShortestPathLengths<-centr$ShortestPathLengths
rownames(ShortestPathLengths)<-colnames(ShortestPathLengths)<-colnames(x)
Res <- list("node.centrality"=centr1, "edge.betweenness.centrality"=edgebet, "ShortestPathLengths"=ShortestPathLengths)
class(Res) <- c("list","centrality_auto")
return(Res)
}
#################################################
## functions to compute clustering coefficient ##
#################################################
# Exported:
clustcoef_auto<-function(x, thresholdWS=0, thresholdON=0)
{
# this function computes several indices of clustering coefficient
# INPUT:
# x is an adjacency matrix or a weight matrix
# thresholdWS is the threshold used for binarizing a weighted network for computing the unweighted
# clustering coefficient by Watts & Strogatz (1998).
# OUTPUT:
# all or a subset of the following indices of clustering coefficient, according to the kind of network
# in input.
# - clustWS: the unweighted clustering coefficient by Watts & Strogatz (1998)
# - signed_clustWS: the generalization of the unweighted clustering coefficient for signed networks
# by Costantini & Perugini (in press)
# - clustZhang: the weighted clustering coefficient by Zhang & Horvath (2005).
# - signed_clustZhang: the generalization of the clustering coefficient by Zhang & Horvath to signed networks
# by Costantini & Perugini (in press)
# - clustOnnela: the weighted clustering coefficient by Onnela et al. (2005)
# - signed_clustOnnela: the generalization of the clustering coefficient by Onnela et al. to signed networks
# by Costantini & Perugini (in press)
# -clustBarrat: the weighted clustering coefficient by Barrat et al. (2004)
# require(igraph)
# Compute weights matrix:
x <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(x))
{
return(lapply(x, clustcoef_auto, thresholdWS=thresholdWS, thresholdON=thresholdWS))
}
# check adjacency matrix (this code is mostly borrowed from package WGCNA, function checkAdjMat)
dim = dim(x)
if (is.null(dim) || length(dim) != 2)
stop("adjacency is not two-dimensional")
if (!is.numeric(x))
stop("adjacency is not numeric")
if (dim[1] != dim[2])
stop("adjacency is not square")
if (max(abs(x - t(x)), na.rm = TRUE) > 1e-12)
stop("adjacency is not symmetric")
if (min(x, na.rm = TRUE) < -1 || max(x, na.rm = TRUE) > 1)
x<-x/max(abs(x))
#####################
weighted.gr<-ifelse(all(abs(x)%in%c(0,1)), FALSE, TRUE) # detect whether the graph is weighted
signed.gr<-ifelse(all(x>=0), FALSE, TRUE) # detect whether the graph is weighted
# compute Barrat clustering coefficient
net_ig<-graph.adjacency(adjmatrix=abs(x), mode="undirected", weighted=(if(weighted.gr)TRUE), diag=FALSE)
cb<-transitivity(net_ig, type="barrat", isolates="zero")
# compute the other measures of clustering coefficient
cw<-clustWS(x, thresholdWS)
cz<-clustZhang(x)
co<-clustOnnela(x, thresholdON)
if (!signed.gr &! weighted.gr) output<-cbind("clustWS"=cw[,1])
if (!signed.gr & weighted.gr) output<-cbind("clustWS"=cw[,1], "clustZhang"=cz[,1], "clustOnnela"=co[,1], "clustBarrat"=cb)
if (signed.gr & !weighted.gr) output<-cbind("clustWS"=cw[,1], "signed_clustWS"=cw[,2])
if (signed.gr & weighted.gr) output<-cbind("clustWS"=cw[,1], "signed_clustWS"=cw[,2], "clustZhang"=cz[,1], "signed_clustZhang"=cz[,2], "clustOnnela"=co[,1], "signed_clustOnnela"=co[,2], "clustBarrat"=cb)
# nodes for which the clustering coefficient cannot be computed have now NaN
# this puts their value to zero
output[is.na(output)]<-0
Res <- data.frame(output)
class(Res) <- c("data.frame","clustcoef_auto")
rownames(Res) <- colnames(x)
return(Res)
}
clustWS<-function(x, thresholdWS=0)
{
# Compute weights matrix:
W <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(W))
{
return(lapply(W, clustWS, thresholdWS=thresholdWS))
}
threshold<-thresholdWS
diag(W)<-0
A<-matrix(0, nrow=nrow(W), ncol=ncol(W))
A[W>threshold]<-1
A[W<(-threshold)]<--1
diag(A)<-0
a_A<-abs(A)
a_num<-diag(a_A%*%a_A%*%a_A)
num<-diag(A%*%A%*%A)
ki<-colSums(abs(A))
den<-ki*(ki-1)
cW<-num/den
a_cW<-a_num/den
data.frame(cbind("clustWS"=a_cW, "signed_clustWS"=cW))
}
clustZhang<-function(x)
{
# Compute weights matrix:
W <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(W))
{
return(lapply(W, clustZhang))
}
# this function has been adapted from package WGCNA
diag(W)<-0
a_W<-abs(W)
num<-diag(W%*%W%*%W)
a_num<-diag(a_W%*%a_W%*%a_W)
den<-colSums(a_W)^2-colSums(W^2)
cZ<-num/den
a_cZ<-a_num/den
data.frame(cbind("clustZhang"=a_cZ, "signed_clustZhang"=cZ))
}
clustOnnela<-function(x, thresholdON=0)
{
# Compute weights matrix:
W <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(W))
{
return(lapply(W, clustOnnela, thresholdON = thresholdON))
}
threshold<-thresholdON
diag(W)<-0
W[abs(W)<threshold]<-0
a_W<-abs(W)
a_W13<-a_W^(1/3)
W13<-matrix(nrow=nrow(W), ncol=ncol(W))
W13[W>=0]<-a_W13[W>=0]
W13[W<0]<-(abs(W[W<0])^(1/3))*(-1)
num<-diag(W13%*%W13%*%W13)
a_num<-diag(a_W13%*%a_W13%*%a_W13)
A<-matrix(0, nrow=nrow(W), ncol=ncol(W))
A[abs(W)>threshold]<-1
ki<-colSums(A)
den<-ki*(ki-1)
cO<-num/den
a_cO<-a_num/den
data.frame(cbind("clustOnnela"=a_cO, "signed_clustOnnela"=cO))
}
##################################
# evaluation of smallworldness #
################################
# Exported:
smallworldness<-function(x, B=1000, up=.995, lo=.005)
{
#compute the small worldness of Humphries & Gurney (2008)
# require(igraph)
# require(sna)
# Compute weights matrix:
x <- getWmat(x)
# If list of matrices, return list of output:
if (is.list(x))
{
return(lapply(x, smallworldness, B=B, up=up, lo=lo))
}
# consider only the adjacency matrix
A<-x!=0
# transitivity of A
A<-graph.adjacency(A, mode="undirected", diag=F, weighted=NULL)
N<-vcount(A)
m<-ecount(A)
clusttrg<-transitivity(A, type="global", isolates="zero")
lengthtrg<-average.path.length(graph=A, directed=F, unconnected=F)
#generate B rnd networks with the same degree distribution of A
deg.dist<-igraph::degree(A, mode="all", loops=F)
rndA<-lapply(1:B, function(x)degree.sequence.game(deg.dist, method="simple.no.multiple"))
# compute the average (global) clustering coefficient over the B random networks
clustrnd<-sapply(rndA, transitivity, type="global", isolates="zero")
clustrnd_m<-mean(clustrnd)
# compute the upper and lower quantiles
clustrnd_lo<-quantile(clustrnd, lo)
clustrnd_up<-quantile(clustrnd, up)
# compute the average shortest path length in random networks, the shortest path
# length among unconnected nodes is computed as N, i.e., 1 plus the max possible path length
lengthrnd<-sapply(rndA, average.path.length, directed=F, unconnected=F)
lengthrnd_m<-mean(lengthrnd)
# compute the upper and lower quantiles
lengthrnd_lo<-quantile(lengthrnd, lo)
lengthrnd_up<-quantile(lengthrnd, up)
# compute humphries&gourney(2008) smallworld-ness
sigma<-(clusttrg/clustrnd_m)/(lengthtrg/lengthrnd_m)
c("smallworldness"=sigma, "trans_target"=clusttrg, "averagelength_target"=lengthtrg, "trans_rnd_M"=clustrnd_m, "trans_rnd_lo"=unname(clustrnd_lo), "trans_rnd_up"=unname(clustrnd_up), "averagelength_rnd_M"=lengthrnd_m, "averagelength_rnd_lo"=unname(lengthrnd_lo), "averagelength_rnd_up"=unname(lengthrnd_up))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.