揭示 igraph 中的交互集群
revealing clusters of interaction in igraph
我有一个交互网络,我使用以下代码制作邻接矩阵,随后计算网络节点之间的相异性,然后将它们聚类以形成模块:
ADJ1=abs(adjacent-mat)^6
dissADJ1<-1-ADJ1
hierADJ<-hclust(as.dist(dissADJ1), method = "average")
现在我希望在绘制 igraph 时显示这些模块。
g<-simplify(graph_from_adjacency_matrix(adjacent-mat, weighted=T))
plot.igraph(g)
然而,到目前为止,我发现将 hclust 输出转换为图形的唯一方法是按照以下教程:http://gastonsanchez.com/resources/2014/07/05/Pretty-tree-graph/
phylo_tree = as.phylo(hierADJ)
graph_edges = phylo_tree$edge
graph_net = graph.edgelist(graph_edges)
plot(graph_net)
这对分层沿袭很有用,但我只想要与集群密切交互的节点,如下所示:
任何人都可以推荐如何使用诸如来自 igraph 的组件之类的命令来显示这些集群吗?
igraph 提供了一堆不同的 layout algorithms 用于在图中放置节点。
像这样的加权网络的一个很好的起点是 force-directed layout(由 layout.fruchterman.reingold
在 igraph 中实现)。
下面是一个使用力导向布局的例子,使用了一些简单的模拟数据。
首先,我们创建一些模拟数据和集群,以及一些 "noise" 以使其更真实:
library('dplyr')
library('igraph')
library('RColorBrewer')
set.seed(1)
# generate a couple clusters
nodes_per_cluster <- 30
n <- 10
nvals <- nodes_per_cluster * n
# cluster 1 (increasing)
cluster1 <- matrix(rep((1:n)/4, nodes_per_cluster) +
rnorm(nvals, sd=1),
nrow=nodes_per_cluster, byrow=TRUE)
# cluster 2 (decreasing)
cluster2 <- matrix(rep((n:1)/4, nodes_per_cluster) +
rnorm(nvals, sd=1),
nrow=nodes_per_cluster, byrow=TRUE)
# noise cluster
noise <- matrix(sample(1:2, nvals, replace=TRUE) +
rnorm(nvals, sd=1.5),
nrow=nodes_per_cluster, byrow=TRUE)
dat <- rbind(cluster1, cluster2, noise)
colnames(dat) <- paste0('n', 1:n)
rownames(dat) <- c(paste0('cluster1_', 1:nodes_per_cluster),
paste0('cluster2_', 1:nodes_per_cluster),
paste0('noise_', 1:nodes_per_cluster))
接下来,我们可以使用Pearson correlation构造我们的邻接矩阵:
# create correlation matrix
cor_mat <- cor(t(dat))
# shift to [0,1] to separate positive and negative correlations
adj_mat <- (cor_mat + 1) / 2
# get rid of low correlations and self-loops
adj_mat <- adj_mat^3
adj_mat[adj_mat < 0.5] <- 0
diag(adj_mat) <- 0
使用 hclust
和 cutree
对数据进行聚类:
# convert to dissimilarity matrix and cluster using hclust
dissim_mat <- 1 - adj_mat
dend <- dissim_mat %>%
as.dist %>%
hclust
clusters = cutree(dend, h=0.65)
# color the nodes
pal = colorRampPalette(brewer.pal(11,"Spectral"))(length(unique(clusters)))
node_colors <- pal[clusters]
最后,从邻接矩阵创建一个 igraph 图并使用 fruchterman.reingold
布局绘制它:
# create graph
g <- graph.adjacency(adj_mat, mode='undirected', weighted=TRUE)
# set node color and plot using a force-directed layout (fruchterman-reingold)
V(g)$color <- node_colors
coords_fr = layout.fruchterman.reingold(g, weights=E(g)$weight)
# igraph plot options
igraph.options(vertex.size=8, edge.width=0.75)
# plot network
plot(g, layout=coords_fr, vertex.color=V(g)$color)
在上面的代码中,我生成了两个 "clusters" 的相关行,以及第三组 "noise".
层次聚类 (hclust
+ cuttree
) 用于将数据点分配给聚类,它们根据聚类成员身份进行着色。
结果如下所示:
有关使用 igraph 聚类和绘制图形的更多示例,请查看:http://michael.hahsler.net/SMU/LearnROnYourOwn/code/igraph.html
您没有分享一些玩具数据供我们使用并提出改进代码的建议,但您的问题表明您只对清楚地绘制集群感兴趣 - 即图形表示。
虽然igraph
自带了一些不错的force directed layout algorithms,比如layout.fruchterman.reingold
、layout_with_kk
等,但是在节点数量多的情况下,很快就会变得难以解释和理解。
像这样:
使用这些可视化网络的传统方法,
- 布局算法,而不是数据,决定了可视化效果
- 类似的网络最终可能会以非常不同的方式呈现
- 大量节点会使可视化难以解释
相反,我发现 Hive Plots 更擅长显示重要的网络属性,在您的实例中,这些属性是集群和边缘。
对于您的情况,您可以:
- 在不同的直线上绘制每个簇
- 智能排序节点的放置,使具有特定属性的节点放置在每条直线的最末端或最开始
- 为边缘着色以识别边缘方向
要做到这一点,您需要:
- 使用
ggnetwork
包将您的 igraph 对象转换为数据框
- 将您的集群映射到此数据帧中存在的节点
- 生成直线坐标并将其映射到每个集群
- 使用
ggplot
可视化
如果您希望使用打包解决方案,R 中还有一个 hiveR
包。您可能还会发现另一种非常有用的图形可视化技术:BioFabric
我有一个交互网络,我使用以下代码制作邻接矩阵,随后计算网络节点之间的相异性,然后将它们聚类以形成模块:
ADJ1=abs(adjacent-mat)^6
dissADJ1<-1-ADJ1
hierADJ<-hclust(as.dist(dissADJ1), method = "average")
现在我希望在绘制 igraph 时显示这些模块。
g<-simplify(graph_from_adjacency_matrix(adjacent-mat, weighted=T))
plot.igraph(g)
然而,到目前为止,我发现将 hclust 输出转换为图形的唯一方法是按照以下教程:http://gastonsanchez.com/resources/2014/07/05/Pretty-tree-graph/
phylo_tree = as.phylo(hierADJ)
graph_edges = phylo_tree$edge
graph_net = graph.edgelist(graph_edges)
plot(graph_net)
这对分层沿袭很有用,但我只想要与集群密切交互的节点,如下所示:
任何人都可以推荐如何使用诸如来自 igraph 的组件之类的命令来显示这些集群吗?
igraph 提供了一堆不同的 layout algorithms 用于在图中放置节点。
像这样的加权网络的一个很好的起点是 force-directed layout(由 layout.fruchterman.reingold
在 igraph 中实现)。
下面是一个使用力导向布局的例子,使用了一些简单的模拟数据。
首先,我们创建一些模拟数据和集群,以及一些 "noise" 以使其更真实:
library('dplyr')
library('igraph')
library('RColorBrewer')
set.seed(1)
# generate a couple clusters
nodes_per_cluster <- 30
n <- 10
nvals <- nodes_per_cluster * n
# cluster 1 (increasing)
cluster1 <- matrix(rep((1:n)/4, nodes_per_cluster) +
rnorm(nvals, sd=1),
nrow=nodes_per_cluster, byrow=TRUE)
# cluster 2 (decreasing)
cluster2 <- matrix(rep((n:1)/4, nodes_per_cluster) +
rnorm(nvals, sd=1),
nrow=nodes_per_cluster, byrow=TRUE)
# noise cluster
noise <- matrix(sample(1:2, nvals, replace=TRUE) +
rnorm(nvals, sd=1.5),
nrow=nodes_per_cluster, byrow=TRUE)
dat <- rbind(cluster1, cluster2, noise)
colnames(dat) <- paste0('n', 1:n)
rownames(dat) <- c(paste0('cluster1_', 1:nodes_per_cluster),
paste0('cluster2_', 1:nodes_per_cluster),
paste0('noise_', 1:nodes_per_cluster))
接下来,我们可以使用Pearson correlation构造我们的邻接矩阵:
# create correlation matrix
cor_mat <- cor(t(dat))
# shift to [0,1] to separate positive and negative correlations
adj_mat <- (cor_mat + 1) / 2
# get rid of low correlations and self-loops
adj_mat <- adj_mat^3
adj_mat[adj_mat < 0.5] <- 0
diag(adj_mat) <- 0
使用 hclust
和 cutree
对数据进行聚类:
# convert to dissimilarity matrix and cluster using hclust
dissim_mat <- 1 - adj_mat
dend <- dissim_mat %>%
as.dist %>%
hclust
clusters = cutree(dend, h=0.65)
# color the nodes
pal = colorRampPalette(brewer.pal(11,"Spectral"))(length(unique(clusters)))
node_colors <- pal[clusters]
最后,从邻接矩阵创建一个 igraph 图并使用 fruchterman.reingold
布局绘制它:
# create graph
g <- graph.adjacency(adj_mat, mode='undirected', weighted=TRUE)
# set node color and plot using a force-directed layout (fruchterman-reingold)
V(g)$color <- node_colors
coords_fr = layout.fruchterman.reingold(g, weights=E(g)$weight)
# igraph plot options
igraph.options(vertex.size=8, edge.width=0.75)
# plot network
plot(g, layout=coords_fr, vertex.color=V(g)$color)
在上面的代码中,我生成了两个 "clusters" 的相关行,以及第三组 "noise".
层次聚类 (hclust
+ cuttree
) 用于将数据点分配给聚类,它们根据聚类成员身份进行着色。
结果如下所示:
有关使用 igraph 聚类和绘制图形的更多示例,请查看:http://michael.hahsler.net/SMU/LearnROnYourOwn/code/igraph.html
您没有分享一些玩具数据供我们使用并提出改进代码的建议,但您的问题表明您只对清楚地绘制集群感兴趣 - 即图形表示。
虽然igraph
自带了一些不错的force directed layout algorithms,比如layout.fruchterman.reingold
、layout_with_kk
等,但是在节点数量多的情况下,很快就会变得难以解释和理解。
像这样:
使用这些可视化网络的传统方法,
- 布局算法,而不是数据,决定了可视化效果
- 类似的网络最终可能会以非常不同的方式呈现
- 大量节点会使可视化难以解释
相反,我发现 Hive Plots 更擅长显示重要的网络属性,在您的实例中,这些属性是集群和边缘。
对于您的情况,您可以:
- 在不同的直线上绘制每个簇
- 智能排序节点的放置,使具有特定属性的节点放置在每条直线的最末端或最开始
- 为边缘着色以识别边缘方向
要做到这一点,您需要:
- 使用
ggnetwork
包将您的 igraph 对象转换为数据框 - 将您的集群映射到此数据帧中存在的节点
- 生成直线坐标并将其映射到每个集群
- 使用
ggplot
可视化
如果您希望使用打包解决方案,R 中还有一个 hiveR
包。您可能还会发现另一种非常有用的图形可视化技术:BioFabric