Vertex reciprocity - social network analysis on r - r

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!

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

Related

Find the number of cities with one outgoing road

I'm practicing for my entrance exam. There are some sample tests available for candidates and I want to solve them before appearing for the exam. But facing problem with the following question.
If anyone can help me solve this, would be highly appreciated.
There are 15 main cities in one country. Some of them are connected by roads.
Besides,
a) You can get from each one city to any other one by a single route;
b) There is only one city with 2 outgoing roads. The other cities have either
1 or 3 outgoing roads.
What is the number of cities with one outgoing road?
Thanks in advance.
Because of a) we can say that this is a tree structure. And in trees the number of edges are one less than number of nodes. Therefore there are only 14 roads. If the number of cities with one outgoing road is x, then 1 * x + 2 * 1 + 3 * (14 - x) = 2 * 14 Which gives us x = 8.

Calculate the number of trips in graph traversal

Hello Stack Overflow Community,
I'm attempting to solve this problem:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1040
The problem is to find the best path based on capacity between edges. I get that this can be solved using Dynamic Programming, I'm confused by the example they provide:
According to the problem description, if someone is trying to get 99 people from city 1 to 7, the route should be 1-2-4-7 which I get since the weight of each edge represents the maximum amount of passengers that can go at once. What I don't get is that the description says that it takes at least 5 trips. Where does the 5 come from? 1-2-4-7 is 3 hops, If I take this trip I calculate 4 trips, since 25 is the most limited hop in the route, I would say you need 99/25 or at least 4 trips. Is this a typo, or am I missing something?
Given the first line of the problem statement:
Mr. G. works as a tourist guide.
It is likely that Mr. G must always be present on the bus, thus the equation for the number of trips is:
x = (ceil(x) + number_of_passengers) / best_route
rather than simply:
x = number_of_passengers / best_route
or, for your numbers:
x = (ceil(x) + 99) / 25
Which can be solved with:
x == 4.16 (trips)

How to create network with both edges and isolates using statnet/igraph

My question is similar to the one posted here: Network adding edges error
I am creating a network from scratches: I have data about 228 vertices, over a period of 13 years. In the first year, I have just 1781 edges: they do not involve all of my vertices (barely 164), therefore the remaining nodes should result as isolated.
I created the network starting from my edgelist, using the code
fdi.graph.2003 <- graph_from_data_frame(fdi.edge.2003, directed = T, vertices = fdi.attr.2003)
where fdi.edge.2003 is a data.frame containing edge attributes (including some potential weight columns): it only involves 164 vertices out of the total vertices defined by fdi.attr.2003 is a data.frame containing a row for each vertex that is involved in the edgelist (164 in total).
all i get is a network with 164 vertices and no isolates. However, I know they do exist in my data! Any suggestion on how to do it? I think that I shoul initialize a network with all 228 vertices, adding their attributes and then adding the edges. However, nothing I am trying is working: rather, I am receiving the most disparate errors related to "Illegal vertex reference in addEdges_R".
Any suggestion is more than welcome, also in the case it would involve the alternative package igraph, for which I am finding the same problem
Filippo
Use add.isolates from the sna package
net1 = as.network(cbind(1:3, 3:5)) #5 vertices, 3 edges
net2 = as.network(add.isolates(net1, 10), matrix.type = "edgelist") #15 v, 3 e
And then you'll probably want to create new vertex names, e.g.
net2%v%"vertex.names" = 1:15

Get node descendants in a tree graph

I have a directed graph (grafopri1fase1) the graph has no loops and it has a tree structure (not binary tree).
I have an array of nodes (meterdiretti) that i have extracted from the graph (grafopri1fase1) matching a condition.
I would like to know starting from each node of Meterdiretti how many nodes are under each node of Meterdiretti.
The result I would like to have is a Matrix with the following format
first column------------ second column
meterdiretti[1] -------- total amount of nodes reachable starting from meterdiretti[1]
meterdiretti[2] -------- total amount of nodes reachable starting from meterdiretti[2]
....
meterdiretti[n] ----------total amount of nodes reachable starting from meterdiretti[n]
Take a punt at what you want - it would be good if you could add a reproducible example to your question.
I think what you want is to count the descendents of a node. You can do this with neighborhood.size and mode="out" argument.
library(igraph)
# create a random graph
g <- graph.tree(17, children = 2)
plot(g, layout=layout.reingold.tilford)
# test on a single node
neighborhood.size( g, vcount(g), "1", "out") - 1
# [1] 16
# apply over a few nodes
neighborhood.size( g, vcount(g), c(1,4,7), "out") - 1
[1] 16 4 2

igraph edge between two vertices

I'm new to R and igraph and I was wondering if anybody can help me with the following.
I want to find the edge weight between two vertices in a graph. My graph structure is defined by the normal ego (node1), alter (node2) and the weight of the edge between them.
I know that I can get the weight for each of the edges in the list of edges that originate from node number 5 using E(igraph_friendship) [ from(5) ]$weight
And that I can find the weight for each of the edges in the list of edges that end onto node number 10 using E(igraph_friendship) [ to(10) ]$weight
But what if I simply want to find the weight of the edge that simple connects just node 5 and node 10?
Alternatively, if I can get the identifier of the edge that connects node 5 and 10 in the list of all edges, E(igraph_friendship), that would work too.
Thanks a lot for your help, I've been looking around a lot for it and I really appreciate your help!
Gabor's use of the adjacency matrix helped. However, it took me a while to figure out how to get my edge lists with weights into an adjacency matrix. I tried to do it the usual way using graph.data.frame but then would get a weird error when I tried translating the igraph object to and adjacency matrix (error: Error in .M.kind(x) : not yet implemented for matrix w/ typeof character). This post helped do the trick: https://sites.google.com/site/daishizuka/toolkits/sna/weighted-edgelists.
However, what I found out from the R help email list help to work best was this simple operator directly on the igraph object: E(g)[5 %--% 10]$weight. See http://igraph.sourceforge.net/doc/R/iterators.html for details
This is actually quite easy in igraph 0.6 and above, because you can
treat the graph as if it was an adjacency matrix (or weighed adjacency
matrix in your case):
library(igraph)
g <- graph.ring(10)
g[1,2]
# [1] 1
E(g)$weight <- runif(ecount(g))
g[1,2]
# [1] 0.8115639
If you want to do this for the whole matrix, then you can simply do
g[]
Or, if you don't want sparse matrices, then
g[sparse=FALSE]
Please see ?"[.igraph" for more.

Resources