I am going to assume that you have a simple graph, that is no loops and no multiple links between nodes. In that case, it is fairly easy to compute this. What does it mean for a link to be reciprocated? When there is a link from a to b, there is a link back from b to a. That means that there is a path of length two from a to itself a->b->a
. How many such paths are there? If A is the adjacency matrix, then the entries of AA gives the number of paths of length two. We only want the ones from a node to itself, so we want the diagonal of AA. This will only count a->b->a
as one path, but you want to count it twice: once for the link a->b
and once for b->a
. So for each node you can get the number of reciprocated links from 2*diag(A*A)
. You want to divide by the total number of links to and from a which is just the degree.
Let me show the computation with an example. Since you do not provide any data, I will use the Enron email data that is available in the 'igraphdata' package. It has loops and multiple links which i will remove. It also has a few isolated vertices, which I will also remove. That will leave us with a connected, directed graph with no loops.
library(igraph)
library(igraphdata)
data(enron)
enron = simplify(enron)
## remove two isolated vertices
enron = delete_vertices(enron, c(72,118))
Now the reciprocity computation is easy.
EnronAM = as.matrix(as_adjacency_matrix(enron))
Path2 = diag(EnronAM %*% EnronAM)
degree(enron)
VertRecip = 2*Path2 / degree(enron)
Let's check it by walking through one node in detail. I will use node number 1.
degree(enron,1)
[1] 10
ENDS = ends(enron, E(enron))
E(enron)[which(ENDS[,1] == 1)]
+ 6/3010 edges from b72ec54:
[1] 1-> 10 1-> 21 1-> 49 1-> 91 1->104 1->151
E(enron)[which(ENDS[,2] == 1)]
+ 4/3010 edges from b72ec54:
[1] 10->1 21->1 105->1 151->1
Path2[1]
[1] 3
Node 1 has degree 10; 6 edges out and 4 edges in. Recip shows that there are three paths of length 2 from 1 back to itself.
1->10->1
1->21->1
1->151->1
That makes 6 reciprocated links and 4 unreciprocated links. The vertex reciprocity should be 6/10 = 0.6 which agrees with what we computed above.
VertRecip[1]
[1] 0.6