如何使用R中的igraph删除小社区?

6
我已经从我的数据集 "allgenes" 创建了我的 igraph,并基于Louvain方法发现了社区模块。
gD <- igraph::simplify(igraph::graph.data.frame(allgenes, directed=FALSE))
lou <- cluster_louvain(gD)

在绘制模块时,我注意到有几个小社群需要删除。如何删除包含5个及以下节点的社群?

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

使用区分模块的图表:

img


1
当寻求帮助时,您应该包含一个简单的可再现示例,其中包括样本输入和期望输出,可用于测试和验证可能的解决方案。 - MrFlick
1
正如MrFlick所暗示的那样,您能否包含一个lou的样本? - gos
3个回答

7

由于您没有提供示例,我将使用随机生成的数据进行说明。

## 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

已删除小型社区


1
非常好的绘图方式。 - akrun
尽管在你给出的例子中它能够工作,但是实际上并不总是有效。根据集群算法,在对诱导子图进行重新聚类时,并不总会得到相同的簇。 - hermidalc

2
如果你想在保留其他现有社区的同时删除某些社区,你不能创建一个由你想要保留的顶点组成的诱导子图并在子图上进行聚类,因为结果社区很可能会改变。
一个可行的方法是手动对社区对象进行子集化。
另外,如果你想绘制原始图形和社区以及新的社区,并且在所有地方都保持相同的颜色,则需要执行几个额外的步骤。
Original Answer: "最初的回答"
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


0

请允许我补充一下。在可视化时,我想要“去除”小社区的颜色,但是保留它们在图中的位置。例如,我有很多孤立点,这会导致一些视觉上的混乱,而我有一个非常有趣的核心组件,查看它们可以得到很好的表示。

我从上面的代码开始。这不是问题,因为我不想要子图:

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

这个方法已经足够好了,但是有没有更聪明的方法来做到这一点呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接