比较图中具有不同数量顶点的社区

时间:2019-02-22 16:33:29

标签: r dplyr igraph

我正在根据通讯数据图计算窗框社区,其中顶点表示大型项目中的表演者。这些图代表不同的通信方法(例如,电子邮件,电话)。

我们想尝试从他们的交流数据中识别表演者团队。由于表演者偏爱不同的通信方法,因此图表的大小不同,并且可能具有一些独特的顶点,而这两种顶点可能都不存在。当我尝试比较各个图中的社区对象时,igraph :: compare()引发异常。参见下面的玩具代表。

在构造图和社区对象以使其大小相同之前,我考虑了顶点列表的dplyr :: full_join()或inner_join(),但是担心这样做会对最终的cluster_louvain()解决方案产生影响。

关于如何通过这些不同的通信方法将社区对象彼此进行比较的想法?预先感谢!

library(tidyverse, warn.conflicts = FALSE)
library(igraph, warn.conflicts = FALSE)

nodes <- as_tibble(list(id = c("sample1", "sample2", "sample3")))
edge <- as_tibble(list(from = "sample1",
                       to = "sample2"))
net <- graph_from_data_frame(d = edge, vertices = nodes, directed = FALSE)
com <- cluster_louvain(net)

nodes2 <- as_tibble(list(id = c("sample1","sample21", "sample22","sample23"
                                )))
edge2 <- as_tibble(list(from = c("sample1", "sample21"),
                       to = c("sample21", "sample22")))
net2 <- graph_from_data_frame(d = edge2, vertices = nodes2, directed = FALSE)
com2 <- cluster_louvain(net2)

# # uncomment to see graph plots
# plot.igraph(net, mark.groups = com)
# plot.igraph(net2, mark.groups = com2)

compare(com, com2)
#> Error in i_compare(comm1, comm2, method): At community.c:3106 : community membership vectors have different lengths, Invalid value

reprex package(v0.2.1)于2019-02-22创建

1 个答案:

答案 0 :(得分:0)

(我不相信)您将无法比较包含两个不同节点集的两个不同图形的聚类算法。实际上,您无法在igraph中做到这一点,并且在概念上很难做到这一点,因为比较聚类算法的方式是通过考虑图中的所有节点对,然后检查它们是否位于相同的群集中或每个节点中的不同群集中两种聚类方法中的一种。如果两种聚类方法通常将相同的节点放在一起,并将相同的节点分开,则它们被认为更相似。 1

我想解决该问题的另一种有效方法是评估仅用于两个图的交集的节点集的聚类方案有多相似。您必须决定在您的设置中什么更有意义。我将展示如何使用节点的并集而不是相交来做到这一点。

因此,您需要两个图中的所有相同节点才能进行比较。实际上,我认为更简单的方法是将所有相同的节点放在一张图中,并具有不同的边类型。然后,您可以分别计算每种边缘类型的聚类,然后进行比较。希望下面的代码很清楚:

# repeat your set-up
library(tidyverse, warn.conflicts = FALSE)
library(igraph, warn.conflicts = FALSE)

nodes <- as_tibble(list(id = c("sample1", "sample2", "sample3")))
edge <- as_tibble(list(from = "sample1",
                       to = "sample2"))

nodes2 <- as_tibble(list(id = c("sample1","sample21", "sample22","sample23")))
edge2 <- as_tibble(list(from = c("sample1", "sample21"),
                        to = c("sample21", "sample22")))

# approach from a single graph
# concatenate edges
edges <- rbind(edge, edge2)
# create an edge attribute indicating network type
edges$type <- c("phone", "email", "email")
# the set of nodes (across both graphs)
nodes <- unique(rbind(nodes, nodes2))

g <- graph_from_data_frame(d = edges, vertices = nodes, directed = F)

# We cluster over the graph without the email edges
com_phone <- cluster_louvain(g %>% delete_edges(E(g)[E(g)$type=="email"]))
plot(g, mark.groups = com_phone)

# Now we can cluster over the graph without the phone edges
com_email <- cluster_louvain(g %>% delete_edges(E(g)[E(g)$type=="phone"]))
plot(g, mark.groups = com_email)

# Now we can compare
compare(com_phone, com_email)
#> [1] 0.7803552

从图中可以看到,我们选择了在单独的图中发现的相同初始聚类结构,并添加了额外的孤立节点。

1:显然,这是一个模糊的解释。 compare中使用的默认算法来自this paper,对此进行了很好的讨论。