Search code examples
rigraphsocial-networking

Splitting a social network into 2 based on node type with igraph (R)


How would I go about splitting this social network into 2, based on node colour?

https://i.sstatic.net/ZnkBF.jpg

I already have the dataset with the information on the nodes, but I'm unsure how to split them with igraph.

Code:

# Weighted 
V(network)[attrib_info$sex =="M"]$color="tomato2"
V(network)[attrib_info$sex =="F"]$color="lightblue2"
plot.igraph(network,
            vertex.size=10,
            vertex.label.cex=0.0000000000000000001,
            edge.color="black",
            edge.width=E(network)$weight*20)

Solution

  • In order to do that, you need to take control of the layout. That is not hard to do. Since you do not provide your data, I will illustrate using the standard karate data set. I set the random seed to get reproducible results. Then, generate a layout. The karate network comes with a color attribute for the vertices and we want to split the network based on this attribute.

    library(igraph)
    library(igraphdata)     ## for karate
    data(karate)
    
    set.seed(2021)
    LO = scale(layout_nicely(karate))
    plot(karate, layout=LO, rescale=F, vertex.size=20,
        xlim=0.8*range(LO[,1]), ylim=0.8*range(LO[,2]))
    

    karate network

    Notice that I saved the layout in order to get reproducible positions for all of the vertices. But there is something else going on here that warrants discussion: my use of rescale, xlim and ylim. By default, igraph rescales the layout to the range [-1,1]. We want the same positions for all three graphs, so we turn that off with rescale=F. However, igraph still plots only the range from -1 to 1 unless you set xlim and ylim, so I pick a range that will show all of the nodes without excessive whitespace around the graph.

    Now we want to break out the two subnetworks by color.

    OV = which(V(karate)$color == 1)
    BV = which(V(karate)$color == 2)
    orange = induced_subgraph(karate, OV)
    blue   = induced_subgraph(karate, BV)
    

    Finally, we want to plot all three on the same graph with the nodes in the same positions. Basically, that is repeating the above plot statement for each of the three networks, selecting just the relevant parts of the layout matrix for each network. I use par to make three graphs on one screen. (And of course, I resized the screen to make it fit these nicely.)

    par(mfrow=c(1,3), mar = c(1,2,1,2))
    plot(karate, layout=LO, rescale=F, vertex.size=20,
        xlim=0.9*range(LO[,1]), ylim=0.85*range(LO[,2]))
    plot(orange, layout=LO[OV, ], rescale=F, vertex.size=20,
        xlim=0.9*range(LO[,1]), ylim=0.85*range(LO[,2]))
    plot(blue, layout=LO[BV, ], rescale=F, vertex.size=20,
        xlim=0.9*range(LO[,1]), ylim=0.85*range(LO[,2]))
    

    Three networks