Inconsistent Local Transitivity Output in igraph

187 Views Asked by At

I need to determine the transitivity for each node in a network, but am getting inconsistent results.

set.seed(123)    
a <- rbinom(144, 1, .5)
b <- graph.adjacency(matrix(a, nrow = 12, ncol = 12), mode = "undirected")

transitivity(b, type = "local")

This provides the output:

 [1] 0.6888889 0.4909091 0.4444444 0.9333333 0.4909091 0.7500000 0.7333333 0.4666667 0.7333333 0.4222222 0.5000000
[12] 0.6944444

But when I try to specify a single node, some values in the output do not match:

transitivity(b, vids = 2, type = "local")

[1] 0.75

In fact, when I try to calculate the local transitivity for all vertices, many are different than if I leave the vids argument out. In some instances when I've tried this, all have been different.

transitivity(b, vids = V(b), type = "local")

  [1] 0.6888889 0.7500000 0.7142857 0.9333333 0.7500000 0.7500000 0.7333333 0.7500000 0.7333333 0.6785714 0.8571429
[12] 0.6944444

If I set vids as NULL it matches the first output, without the vids argument included at all.

The results are slightly different, but still don't match if I create a directed network.

Any thoughts on what might be causing this or which set of results should I use?

Thank you for your help.

2

There are 2 best solutions below

3
ThomasIsCoding On BEST ANSWER

You should be aware of that your graph b is NOT a simple graph, since it contains self loops

enter image description here

When running transitivity over such kind of graph, you will see a warning/error message

Transitivity works on simple graphs only. The result might be incorrect. igraph 1.3.0 and later will treat this as an error.

Thus, if you would like to use transitivity in a correct manner, you should exclude self loops first, e.g.,

b <- simplify(graph.adjacency(matrix(a, nrow = 12, ncol = 12), mode = "undirected"))

and then you will see

> transitivity(b, type = "local")
 [1] 0.6888889 0.7500000 0.7142857 0.9333333 0.7500000 0.7500000 0.7333333
 [8] 0.7500000 0.7333333 0.6785714 0.8571429 0.6944444

> transitivity(b, vids = V(b), type = "local")
 [1] 0.6888889 0.7500000 0.7142857 0.9333333 0.7500000 0.7500000 0.7333333
 [8] 0.7500000 0.7333333 0.6785714 0.8571429 0.6944444
4
Szabolcs On

As Thomas said, the result you get from transitivity(b, type = "local") is incorrect because b is not simple, and local transitivity calculations are not supported for non-simple graphs in R/igraph 1.2.x. If you use the latest version, there will be a clear warning:

> transitivity(b, type = "local")
Transitivity works on simple graphs only. The result might be incorrect. igraph 1.3.0 and later will treat this as an error.
 [1] 0.6888889 0.4909091 0.4444444 0.9333333 0.4909091 0.7500000 0.7333333 0.4666667
 [9] 0.7333333 0.4222222 0.5000000 0.6944444

If you don't see this warning, then please updgrade to igraph 1.2.11.

How come that transitivity(b, type='local") and transitivity(b, vids=V(b), type='local") give different results? This is because internally different code paths are used when calculating the result for all vertices vs a specific subset of vertices, in an attempt to improve performance.

The warning message says that "igraph 1.3.0 and later will treat this as an error." but in fact a tremendous amount of improvements have gone into version 1.3 since then and support for multigraphs has already been added (more precisely, this has been added to C/igraph 0.9, which R/igraph 1.3 will be based on).

I encourage you to try the development version of R/igraph, which will become version 1.3.0. Installation instructions are here; note that you need to have the R development tools installed (on Windows/Mac), as the package compiles from source. This version has a large number of fixes compared to the 1.2.x series, and at this point, should be considered more reliable than the "stable" 1.2.11.