Search code examples
rgraphigraphsocial-networking

Contract verticies by attribute with igraph


I am working on a graph, where each node has an attribute "group" of the following: "Baby Product", "Book" "CE" "DVD" "Music" "Software" "Toy" "Video" "Video Games".

I would like to know how to plot a graph reppresenting those communities: there shall be 9 verticies, one for each group, and a link (possibly weighted) each time two nodes of two categories are connected.

I have tried using the igraph contract function, but this is the result:

> contract(fullnet, mapping=as.factor(products$group), vertex.attr.comb = products$group)
Error in FUN(X[[i]], ...) : 
  Unknown/unambigous attribute combination specification
Inoltre: Warning message:
In igraph.i.attribute.combination(vertex.attr.comb) :
  Some attributes are duplicated

I guess I have misunderstood what this function is used for.

Now I am thinking about creating a new edgelist, made like the one before but instead of the Id of each vertex the name of the group. Sadly, I do not know how to do this in a fast way on an edgelist of over 1200000 elements.

Thank you very much in advance.


Solution

  • I think using contract() should be correct. In the example code below, I added an anonymous function to vertex.attr.comb to combine the vertices by group. Then, simplify() removes loop edges and calculate the sum of edge weight.

    # Create example graph
    set.seed(1)
    g <- random.graph.game(10, 0.2)
    V(g)$group <- rep(letters[1:3], times = c(3, 3, 4))
    E(g)$weight <- 1:length(E(g))
    E(g)
    # + 9/9 edges from 7017c6a:
    #   [1] 2-- 3 3-- 4 4-- 7 5-- 7 5-- 8 7-- 8 3-- 9 2--10 9--10
    E(g)$weight
    # [1] 1 2 3 4 5 6 7 8 9
    
    # Contract graph by `group` attribute of vertices
    g1 <- contract(g, factor(V(g)$group),
                   vertex.attr.comb = function(x) levels(factor(x)))
    # Remove loop edges and compute the sum of edge weight by group
    g1 <- simplify(g1, edge.attr.comb = "sum")
    E(g1)
    # + 3/3 edges from a852397:
    #   [1] 1--2 1--3 2--3
    E(g1)$weight
    # [1]  2 15 12