2

I would appreciate help with using decompose.graph, community detection functions from igraph and lapply.

I have an igraph object G with vertex attribute "label" and edge attribute "weight". I want to calculate community memberships using different functions from igraph, for simplicity let it be walktrap.community.

This graph is not connected, that is why I decided to decompose it into connected components and run walktrap.community on each component, and afterwards add a community membership vertex attribute to the original graph G.

I am doing currently the following

comps <- decompose.graph(G,min.vertices=2)
communities <- lapply(comps,walktrap.community)

At this point I get stuck since I get the list object with the structure I cannot figure out. The documentation on decompose.graph tells only that it returns list object, and when I use lapply on the result I get completely confused. Moreover, the communities are numbered from 0 in each component, and I don't know how to supply weights parameter into walktrap.community function.

If it were not for the components, I would have done the following:

wt <- walktrap.community(G, modularity=TRUE, weights=E(G)$weight)
wmemb <- community.to.membership(G, wt$merges,steps=which.max(wt$modularity)-1)
V(G)$"walktrap" <- wmemb$membership

Could anyone please help me solve this issue? Or provide some information/links which could help?

SlowLoris
  • 995
  • 6
  • 28
npobedina
  • 331
  • 3
  • 14

1 Answers1

4

You could use a loop:

library(igraph)
set.seed(2)
G <- erdos.renyi.game(100, 1/50)
comps <- decompose.graph(G,min.vertices=2)
length(comps)  # 2 components, in this example
for(i in seq_along(comps)) { # For each subgraph comps[[i]]
  wt <- walktrap.community(comps[[i]], modularity=TRUE, weights=E(comps[[i]])$weight)
  wmemb <- community.to.membership(comps[[i]], wt$merges,steps=which.max(wt$modularity)-1)
  V(comps[[i]])$"walktrap" <- wmemb$membership
}

It is possible to do it with lapply and mapply, but it is less readable.

comps <- decompose.graph(G,min.vertices=2)
wt <- lapply( comps, function(u)
  walktrap.community(u, modularity=TRUE, weights=E(u)$weight)
)
wmemb <- mapply( 
  function(u,v) community.to.membership(u, v$merges,steps=which.max(v$modularity)-1),
  comps, wt,
  SIMPLIFY=FALSE
)
comps <- mapply( 
  function(u,v) { V(u)$"walktrap" <- v$membership; u },
  comps, wmemb,
  SIMPLIFY=FALSE
)
Vincent Zoonekynd
  • 31,893
  • 5
  • 69
  • 78
  • Thanks a lot for such a quick and precise reply. I do agree that the first option looks much more readable, besides I still don't feel comfortable using "*apply". I have a question about assigning the results to the original graph: `for (i in seq_along(comps)){ for (j in (seq_along(V(comps[[i]]))-1)){ cur <- V(comps[[i]])[j]$id V(G)[V(G)$id==cur]$"walktrap"<-V(comps[[i]])[j]$"walktrap" } }` , where "id" is the unique label on the vertex set. Do you know whether it is the only way to do it? – npobedina Feb 13 '12 at 12:06