1
votes

what I am wondering about is it possible to create overlapping communities in igraph ?

df1 :vertex list and its membership

EDIT:id refer to the vertex name and membership is refer to the vertex community id, so vertex 1 is belong to two communities : 3 and 2

df1<- structure(list(id = c(1L,2L,3L, 4L, 5L,6L, 7L, 8L,9L), membership = list(c(3, 2),c(2),c(1),c(4),
                                                                             c(4, 1),c(2, 4),
                                                                             c(1),c(1, 3),c(2,1,3))),
                                                           .Names = c("id","membership"),class = "data.frame", row.names = c(NA, -9L))
#id membership
#1  1       3, 2
#2  2          2
#3  3          1
#4  4          4
#5  5       4, 1
#6  6       2, 4
#7  7          1
#8  8       1, 3
#9  9    2, 1, 3

df2 : edgelist with edge membership

df2<- structure(list(id1 = c(1L,2L,5L,8L,9L,4L,6L),id2 = c(3L,5L,8L,1L,2L,3L,7L), membership = list(c(1),c(2),c(1,4),c(3,2),
                                                                           c(1,3, 4),c(3),c(1,2))),
            .Names = c("id1","id2","membership"),class = "data.frame", row.names = c(NA, -7L))
    #id1 id2 membership
#1   1   3          1
#2   2   5          2
#3   5   8       1, 4
#4   8   1       3, 2
#5   9   2    1, 3, 4
#6   4   3          3
#7   6   7       1, 2

please consider that we want to create a community object :

  # diffrent membership vector from df1 
mem <-sapply(1:max(sapply(df1$membership, function(x)length(x))),function(y){
  unlist(lapply(df1$membership,function(x) x[y]))})

         # [,1] [,2] [,3]
# [1,]    3    2   NA
# [2,]    2   NA   NA
# [3,]    1   NA   NA
# [4,]    4   NA   NA
# [5,]    4    1   NA
# [6,]    2    4   NA
# [7,]    1   NA   NA
# [8,]    1    3   NA
# [9,]    2    1    3

#create community objects for each membership vector
com<-sapply(1:ncol(mem),function(x) create.communities(membership=mem[,x], algorithm = NULL, merges = NULL,
                        modularity = NULL))

# com
#[[1]]
#Graph community structure calculated with the unknown algorithm
#Number of communities: 4 
#Membership vector:
#[1]  3  2  1  4  4  2  1  1  2

# [[2]]
#Graph community structure calculated with the unknown algorithm
#Number of communities: NA 
#Membership vector:
#[1]  2 NA NA NA  1  4 NA  3  1

#[[3]]
#Graph community structure calculated with the unknown algorithm
#Number of communities: NA 
#Membership vector:
#[1] NA NA NA NA NA NA NA NA  3

   **Edit**:graph=graph.data.frame(df2,directed=FALSE)
    sapply (1:length(com),function(x) plot.communities(com[[x]],graph))

that last line give me an error Error in membership(x) : Cannot calculate community membership as it can not compute Number of communities with NA included in the community membership

So,what would be the solution to create these overlapping communities in igraph ? Thank you in advance and sorry for my long question.

1
This is not supported in igraph AFAIK. create.communities does not work for overlapping communities.Gabor Csardi
thanks for the comment @GaborCsardi , is there any other way to have overlapping communities ?academic.user
I am not sure what you are trying to do here, but you can define your own class for your communities. E.g. just put a different groups in a list.Gabor Csardi
@GaborCsardi,I am not getting your comment unless you are referring to the vertex which are not belong to any communities .I would be grateful if you clarify this for me.what I want to do is to have overlapping communities, I have vertex list along with the community class Ids which they belong to.academic.user
Yes, that's what I am saying. You already have your communities in df1.Gabor Csardi

1 Answers

1
votes
  1. I am unclear what the column names are referring to in df1.
  2. It doesn't seem like you use df2 at all. Why are you defining it?
  3. I get an error when it reaches the function plot.communities. Is this a personal function?
  4. I don't see the variable graph anywhere in the code, so that would produce an error as well.

In any case, when you create mem, it is first using the first value of df1$membership, and then the second, etc. For some (columns 2-4, 7), there is only one element in membership, so it returns NA. You may have to explicitly check for the length of the element.

So something similar to this might be what you want (but replace the ifelse condition if you have to):

mem <- sapply(1:max(sapply(df1$membership, length)), function(y)

sapply(df1$membership, function(x)

ifelse(length(x) < y, x[1], x[y])))

> mem

 [,1] [,2] [,3]

[1,] 3 2 3

[2,] 2 2 2

[3,] 1 1 1

[4,] 4 4 4

[5,] 4 1 4

[6,] 2 4 2

[7,] 1 1 1

[8,] 1 3 1

[9,] 2 1 3

I also changed the code slightly (e.g. got rid of unlist(lapply).

EDIT: Additionally, when creating com, you probably want lapply instead of sapply.