6

I have created my igraph from my dataset "allgenes", and found community modules based on the louvain method.

gD <- igraph::simplify(igraph::graph.data.frame(allgenes, directed=FALSE))
lou <- cluster_louvain(gD)

Plotting the modules, I note that there are several small communities that I wish to remove. How would I remove communities containing 5 nodes or less?

plot(lou, gD, vertex.label = NA, vertex.size=5, edge.arrow.size = .2)

Plot with distinguished modules:

img

camille
  • 16,432
  • 18
  • 38
  • 60
  • 1
    When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Jul 10 '18 at 18:17
  • 1
    As MrFlick alluded to, can you include a sample of what `lou` looks like? – gos Jul 10 '18 at 18:25

3 Answers3

7

Since you do not provide an example, I will illustrate with randomly generated data.

## First create an example like yours
library(igraph)
set.seed(123)
gD = erdos.renyi.game(50,0.05)
lou <- cluster_louvain(gD)
LO = layout_with_fr(gD)
plot(lou, gD, vertex.label = NA, vertex.size=5, 
    edge.arrow.size = .2, layout=LO)

G1

## identify which communities have fewer than 5 members
Small = which(table(lou$membership) < 5)

## Which nodes should be kept?
Keep = V(gD)[!(lou$membership %in% Small)]

## Get subgraph & plot
gD2  = induced_subgraph(gD, Keep)
lou2 = cluster_louvain(gD2)
LO2 = LO[Keep,]
plot(lou2, gD2, vertex.label = NA, vertex.size=5, 
    edge.arrow.size = .2, layout=LO2)

G2

The small communities have been removed

G5W
  • 36,531
  • 10
  • 47
  • 80
  • 1
    Very nice way to plot – akrun Jul 10 '18 at 22:53
  • While it works in the example you gave this does not actually work in general. Depending on the cluster algorithm when you cluster again on the induced subgraph you do not always get the same clusters. – hermidalc Apr 18 '19 at 12:14
2

If you want to remove communities while maintaining the other existing communities you cannot create an induced subgraph with vertices you want to keep and cluster on the subgraph because the resulting communities can very likely change.

A workable approach would be to manually subset the communities object.

Also, if you want to plot the original graph and communities and new ones and maintain the same colors everywhere you have to do a couple additional steps.

suppressPackageStartupMessages(library(igraph))
set.seed(123)

g <- erdos.renyi.game(50, 0.05)
c <- cluster_louvain(g)
l <- layout_with_fr(g)
c_keep_ids <- as.numeric(names(sizes(c)[sizes(c) >= 5]))
c_keep_v_idxs <- which(c$membership %in% c_keep_ids)

g_sub <- induced_subgraph(g, V(g)[c_keep_v_idxs])
# igraph has no direct functionality to subset community objects so hack it
c_sub <- c
c_sub$names <- c$names[c_keep_v_idxs]
c_sub$membership <- c$membership[c_keep_v_idxs]
c_sub$vcount <- length(c_sub$names)
c_sub$modularity <- modularity(g_sub, c_sub$membership, E(g_sub)$weight)

par(mfrow = c(1, 2))
plot(c, g,
  layout = l,
  vertex.label = NA,
  vertex.size = 5
 )
plot(c_sub, g_sub,
  col = membership(c)[c_keep_v_idxs],
  layout = l[c_keep_v_idxs, ],
  mark.border = rainbow(length(communities(c)), alpha = 1)[c_keep_ids],
  mark.col = rainbow(length(communities(c)), alpha = 0.3)[c_keep_ids],
  vertex.label = NA,
  vertex.size = 5
)
par(mfrow = c(1, 1))

communities plots

hermidalc
  • 498
  • 4
  • 12
0

Allow me to add to this. I want to "remove" the color from small communities when visualizing, but keep them in the graph. e.g. I have a lot of isolates and that makes for some visual clutter while I have a very interesting core component, where looking at them gives a good representation.

I am starting with the code above. Not an issue, because I do not want subgraphs:

Small = which(table(g_community$membership) < 2)
g_community$membership[g_community$membership %in% Small] <- 999

This works well enough, but is there a smarter way to do this?

SteffenT
  • 119
  • 6