This is the first post of a series on the concept of “network centrality” with
applications in R and the package netrankr. There is already a rudimentary tutorial for the package, but I wanted to extend
it to a broader tutorial for network centrality. The main focus of the
blog series will be the applications in R and conceptual considerations will only play a minor role.
An extended version of the series will be made available as a bookdown
version (hopefully) early next year.
library(igraph)
library(ggraph)
library(tidyverse)
library(netrankr)
Introduction
Research involving networks has found its place in a lot of disciplines. From
the social sciences to the natural sciences, the buzz-phrase “networks are everywhere”, is everywhere.
One of the many tools to analyze networks are measures of centrality.
In a nutshell, a measure of centrality is an index that assigns a numeric values to
the nodes of the network. The higher the value, the more central the node (A more thorough introduction is given in the extended tutorial). Related ideas can already be found in Moreno’s work in the 1930s, but most relevant ground work was done in the late 1940s to end 1970s. This period includes the work of Bavelas and Leavit on group communication experiments and of course the seminal paper “Centrality in Social Networks: Conceptual Clarification” of Linton Freeman.
If you work, or intend to work, with centrality and haven’t read it, I urge you to do so.
Freeman does not mince matters and goes all-in on criticizing contemporary work of that time.
He calls existing indices “nearly impossible to interpret”, “hideously complex”, “seriously flawed”, “unacceptable”, and “arbitrary and uninterpretable”. His rant culminates in the following statement.
The several measures are often only vaguely related to the intuitive ideas they purport to index,
and many are so complex that it is difficult or impossible to discover what,
if anything, they are measuring.
and he concludes:
There is certainly no unanimity on exactly what centrality is or on its conceptual foundations,
and there is very little agreement in the proper procedure for its measurement.
So, up to the 1970s, many different centrality indices have already been proposed, which assessed different
structural features of networks in order to determine central nodes. But Freeman found this
measures hardly appropriate and criticized their overabundance. He argued that the vast array of indices can be
boiled down to three indices: degree, betweenness and closeness. Everything else was just an awkward
variant of one of these measures. Note though, the indices already existed and were not designed
by him (well, betweenness kind of was; PDF). How was this work received?
As of November 2019, the paper has been cited over 14000 times. It is by far the most
the most influential work in the area of centrality. But did it change how we handle
centrality today? Not really. Consider, for instance, the review paper of
Lü et al. (or my periodic table
of indices.). The list of existing centrality indices is huge and new centrality indices are
still crafted on a regular basis. Thus, it seems that Freeman’s “no unanimity” statement is still
relevant today. The ambiguities surrounding centrality poses many challenges for empirical work.
Some of the reoccurring questions are:
Which index do I choose for my analysis?
Should I maybe design a new one?
How do I validate that the chosen index is appropriate?
While the answer to the second question is easy (Don’t do it!), the others are a bit more tricky.
In this post, I will review existing R Package that are relevant for centrality related analyses
and illustrate why considering the above mentioned questions is necessary.
R packages for centrality
(This section lists a great variety of different indices. If you are interested in the technical details,
consult the help of the function and check out the references)
There are several packages that implement centrality indices for R.
Of course, there are the big network and graph packages such as
igraph,sna, qgraph, and tidygraph, which are designed as general purpose packages
for network analysis. Hence, they also implement some centrality indices.
igraph contains the following 10 indices:
degree (degree())
weighted degree (graph.strength())
betweenness (betweenness())
closeness (closeness())
eigenvector (eigen_centrality())
alpha centrality (alpha_centrality())
power centrality (power_centrality())
PageRank (page_rank())
eccentricity (eccentricity())
hubs and authorities (authority_score() and hub_score())
subgraph centrality (subgraph_centrality())
In most cases, parameters can be adjusted to account for directed/undirected and
weighted/unweighted networks.
The sna package implements roughly the same indices together with:
flow betweenness (flowbet())
load centrality (loadcent())
Gil-Schmidt Power Index (gilschmidt())
information centrality (infocent())
stress centrality (stresscent())
qgraph specializes on weighted networks. It has a generic function centrality_auto()
which returns, depending on the network, the following indices:
degree
strength (weighted degree)
betweenness
closeness
The package also contains the function centrality(), which calculates a non-linear combination
of unweighted and weighted indices using a tuning parameter \(\alpha\) (See Opsahl et al.).
There are also some dedicated centrality packages, such as centiserve, CINNA, influenceR and keyplayer.
The biggest in terms of implemented indices is currently centiserve with a total of 33 indices.
as.character(lsf.str(&quot;package:centiserve&quot;))
## [1] &quot;averagedis&quot; &quot;barycenter&quot; ## [3] &quot;bottleneck&quot; &quot;centroid&quot; ## [5] &quot;closeness.currentflow&quot; &quot;closeness.freeman&quot; ## [7] &quot;closeness.latora&quot; &quot;closeness.residual&quot; ## [9] &quot;closeness.vitality&quot; &quot;clusterrank&quot; ## [11] &quot;communibet&quot; &quot;communitycent&quot; ## [13] &quot;crossclique&quot; &quot;decay&quot; ## [15] &quot;diffusion.degree&quot; &quot;dmnc&quot; ## [17] &quot;entropy&quot; &quot;epc&quot; ## [19] &quot;geokpath&quot; &quot;hubbell&quot; ## [21] &quot;katzcent&quot; &quot;laplacian&quot; ## [23] &quot;leaderrank&quot; &quot;leverage&quot; ## [25] &quot;lincent&quot; &quot;lobby&quot; ## [27] &quot;markovcent&quot; &quot;mnc&quot; ## [29] &quot;pairwisedis&quot; &quot;radiality&quot; ## [31] &quot;salsa&quot; &quot;semilocal&quot; ## [33] &quot;topocoefficient&quot;
The package is maintained by the team behind centiserver,
the “comprehensive centrality resource and server for centralities calculation”.
The website collects indices found in the literature. Currently (December 2018), it lists 235 different indices.
That’s…a lot.
CINNA is a relatively new package (first CRAN submission in 2017). The package description says
“Functions for computing, comparing and demonstrating top informative centrality measures within a network.”
Most of the indices in the package are imported from other package, such as centiserve.
In addition, there are:
Dangalchev closeness (dangalchev_closeness_centrality())
group centrality (group_centrality())
harmonic closeness (harmonic_centrality())
local bridging centrality (local_bridging_centrality())
The function calculate_centralities() can be used to calculate all applicable indices
to a network. The primary purpose of the package is to facilitate the choice of indices
by visual and statistical tools. If you are interested in the details, see this tutorial
and this vignette.
influenceR and keyplayer are comparably small packages which implement only a small
number of indices.
(For now, I deliberately leave out my package netrankr. While it implements a great variety of indices,
it is not its primary purpose to provide a set of predefined measures. We will come to that in
the next part.)
You really have the agony of choice if you look at this exhaustive list of possibilities.
A small example
Let us start with a fairly simple example. Consider the following two small networks.
#data can be found here: https://github.com/schochastics/centrality_tutorial
g1