0

I recently began working on r for social network analysis. Everything goes well and up until now, I found answers to my questions here or on google. But not this time!

I am trying to find a way to calculate "vertex reciprocity" (% of reciprocal edges of each actor of the network). On igraph, reciprocity(g) works fine to calculate the reciprocity of the whole network, but it doesn't help me with the score per actor. Does anybody know what I could do?

Thank you!

Szabolcs
  • 24,728
  • 9
  • 85
  • 174
Ammama
  • 1
  • 1
  • I am not completely sure what you want. I _think_ that what you want for each node is (number of reciprocated edges) / (number of edges) where the numerator counts both the edge in and the edge out and the denominator is all edges in or out. Is that what you want? – G5W Mar 27 '22 at 18:05
  • Yes, that is exactly that. Sorry it wasn't clear. – Ammama Mar 29 '22 at 18:10

1 Answers1

1

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
G5W
  • 36,531
  • 10
  • 47
  • 80