I am using the R programming language and the "igraph" library. I am trying to better understand graph structures for "two mode" graphs (graphs in which there are two types of nodes). In particular, I am trying to understand how to "project" two mode" (to my understanding, these are usually "bipartite") graphs. (https://rpubs.com/pjmurphy/317838)
For instance, I created a graph of relationships between "men" and "women". Although this graph has two modes (men and women), I don't think that this graph is bipartite (since "edges" can exist between the same types of nodes:
library(igraph)
# I don't think this is a bipartite graph
gender_data <- data.frame(
"men" = c("john", "kevin", "mark", "kevin", "kevin", "mark", "henry", "mark", "susan", "john", "henry", "susan", "susan", "janet", "janet", "henry", "henry", "john"),
"women" = c("janet", "janet", "sarah", "lucy", "lucy", "susan", "janet", "susan", "lucy", "kevin", "lucy", "janet", "kevin", "mark", "lucy", "sarah", "mark", "mark")
)
#create directed graph
graph <- graph.data.frame(gender_data, directed=F)
graph <- simplify(graph)
V(graph)["john"]$color<-"red"
V(graph)["kevin"]$color<-"red"
V(graph)["mark"]$color<-"red"
V(graph)["janet"]$color<-"blue"
V(graph)["sarah"]$color<-"blue"
V(graph)["lucy"]$color<-"blue"
V(graph)["henry"]$color<-"red"
V(graph)["susan"]$color<-"blue"
plot(graph)
I read that a better way to understand bipartite graphs is through "actors and movies". Different actors can be in the same movie and one actor can be in different movies - but as such an actor can't share an edge with itself and a movie can not share an edge with itself. Here is my interpretation of such a network:
film_data <- data.frame(
"movie" = c("movie_1", "movie_1", "movie_1", "movie_2", "movie_2", "movie_2", "movie_3", "movie_3", "movie_3", "movie_4", "movie_4", "movie_4", "movie_4", "movie_5", "movie_5", "movie_5", "movie_6", "movie_6"),
"actor" = c("actor_1", "actor_2", "actor_3", "actor_2", "actor_3", "actor_4", "actor_1", "actor_5", "actor_6", "actor_2", "actor_7", "actor_1", "actor_8", "actor_5", "actor_9", "actor_3", "actor_2", "actor_8")
)
#create directed graph
graph <- graph.data.frame(film_data, directed=F)
graph <- simplify(graph)
plot(graph)
However, (according to this stackoverflow post here: valued bipartite projection using R igraph ), this actor graph is still not bipartite (I don't understand why):
is.bipartite(graph)
[1] FALSE
According to the same stackoverflow post, the actor graph can still be converted into a bipartite graph (I don't understand what just happened):
V(graph)$type <- V(graph)$name %in% film_data[,1]
is.bipartite(graph)
[1] TRUE
From here, a projection can be made that "projects" two separate graphs:
proj<-bipartite.projection(graph, V(graph)$type,multiplicity = TRUE)
proj
$proj1
IGRAPH b5bc5ca UNW- 9 16 --
+ attr: name (v/c), weight (e/n)
+ edges from b5bc5ca (vertex names):
[1] actor_1--actor_2 actor_1--actor_3 actor_1--actor_5 actor_1--actor_6 actor_1--actor_7 actor_1--actor_8 actor_2--actor_3 actor_2--actor_4
[9] actor_2--actor_7 actor_2--actor_8 actor_3--actor_4 actor_3--actor_5 actor_3--actor_9 actor_5--actor_6 actor_5--actor_9 actor_7--actor_8
$proj2
IGRAPH b5bc5ca UNW- 6 11 --
+ attr: name (v/c), weight (e/n)
+ edges from b5bc5ca (vertex names):
[1] movie_1--movie_3 movie_1--movie_4 movie_1--movie_2 movie_1--movie_6 movie_1--movie_5 movie_2--movie_4 movie_2--movie_6 movie_2--movie_5
[9] movie_3--movie_4 movie_3--movie_5 movie_4--movie_6
Finally, the two projections can be plotted:
plot(proj$proj1)
plot(proj$proj2)
My questions:
Why wasn't the original actor-movie graph "bipartite"? After all, it was undirected and cyclic .
Why does the line
V(graph)$type <- V(graph)$name %in% film_data[,1]transform the actor-movie graph into a bipartite graph?Is there any reason that
is.bipartite(proj$proj1) 1 FALSE
is.bipartite(proj$proj2) 1 FALSE
How does this line
proj<-bipartite.projection(graph, V(graph)$type,multiplicity = TRUE)"work"? In the original actor-movie graph, I specifically entered the data so that there are no direct relationships between two movies or two actors. For instance, in "proj2" there is a edge between "movie_1" and "movie_2" - how did this happen and why did this happen? In my original data, there is no such direct relationship between movie_1 and movie_2?Suppose actor_1, actor_2, actor_3, actor_4 are male and actor_5, actor_6, actor_7, actor_8, actor_9 are female. Is there a way to now make 3 projections? Projection for male actors, projection for female actors and projections for movies?
Thanks



