0

I am not sure of how to phrase this question, which is making it very hard to find a solution.

I have a graph of people and their relationships in igraph. I also have the location of this people in a dataframe.

> # graph.id is their id in the graph
> people
    user.name   graph.id    location.cell
1   perez       654         54
2   garcia      123         54
3   fernandez   771         32
4   rodriguez   11          81

My graph connects users by their graph.id:

user 654 <-> user 11
user 123 <-> user 11

And I want a new graph with their regions, with a

cell 54 <- weight 2-> cell 81

(there are two connections between cells 54 and 81, 
 one between users 11 and 654, 
 and another between users 11 and 123,
 so weight=2)

How can I do this in R (I'm using igraph)? I've tried a couple of times, iterating over the edges in the graph, but I ended up with too much code that wasn't going to be acceptably fast or mantainable, and it doesn't look like a problem that should be hard (I think I wouldn't have any problem to do this kind of thing in a language I was more comfortable with).

Thanks a lot.

Jk041
  • 934
  • 1
  • 15
  • 33
  • Before I do this as a flag (only for SO housekeeping) is this - http://stackoverflow.com/questions/15367779/how-to-create-a-bipartite-network-in-r-with-igraph-or-tnet - close to what you're looking for? – hrbrmstr Feb 07 '15 at 18:26
  • @hrbrmstr I am not sure.. but looks promising. I'll read through it more carefully and try it. If it is, I'll flag or remove the question mysef. Thanks a lot. – Jk041 Feb 07 '15 at 19:35

1 Answers1

1

You can do this with the graph.data.frame function in igraph, creating a new graph based on the region associated with each edge in your current graph.

First, here's the setup you're describing:

# 654 <-> 11; 123 <-> 11; 123 <-> 771
library(igraph)
g <- graph.data.frame(cbind(c(654, 123, 123), c(11, 11, 771)))
people <- data.frame(graph.id=c(654, 123, 771, 11), location.cell=c(54, 54, 32, 81))

Now you can store the location of each vertex within g and use that vertex attribute to grab the location of each edge endpoint:

V(g)$location <- people$location.cell[match(V(g)$name, people$graph.id)]
g2 <- graph.data.frame(cbind(V(g)$location[get.edges(g, E(g))[,1]],
                             V(g)$location[get.edges(g, E(g))[,2]]), directed=F)
E(g2)
# str(g2)
# IGRAPH UN-- 3 3 -- 
# + attr: name (v/c)
# + edges (vertex names):
# [1] 54--81 54--81 54--32

To convert multiple edges to a single edge with higher weight, you can use simplify:

E(g2)$weight <- 1
g2 <- simplify(g2)
str(g2)
# IGRAPH UNW- 3 2 -- 
# + attr: name (v/c), weight (e/n)
# + edges (vertex names):
# [1] 54--81 54--32
E(g2)$weight
# [1] 2 1
josliber
  • 43,891
  • 12
  • 98
  • 133