【问题标题】:How to merge the repeated nodes into the one node?如何将重复的节点合并为一个节点?
【发布时间】:2019-05-08 11:04:47
【问题描述】:

这个问题是question的继续。

我将n 点与(x, y) 坐标组织在矩阵中,如下所示:

A <- t(matrix(c(
 0, 0, 1, 0, 1,-1, 1,-2, 0,-2,-1,-2,-2,-2,-2,-1,-1,-1, 0,-1, 0, -2, 0,-3,
 0,-4,-1,-4,-1,-3,-1,-2, 0,-2, 1,-2, 2,-2, 2,-3, 1,-3, 0,-3, 0,-2, 0,-1, 0, 0), nrow =2)); 

如您所见,k=8 对重复了 (x,y) 坐标。

编辑。

ids <- which(duplicated(A))
k <- length(ids)

我创建了 igraph 对象g 并绘制它。具有重复坐标的节点在图中用红色表示。有的重复两次,有的重复三四次。

library(igraph)
g <- make_empty_graph(n=nrow(A)) 
g <- g + path(seq_len(nrow(A))) 

V(g)$id    <- seq_len(vcount(g))
V(g)[V(g)$id %in% ids]$color <- "red"


plot(g, layout=as.matrix(A),
     edge.arrow.size = 0.3,
     edge.curved = TRUE
)

我需要将坐标重复的节点合并为一个节点。

问题。 是否可以将坐标重复的节点合并为一个节点?重复的边缘也应该合并到一个边缘。边缘的方向可以省略。

【问题讨论】:

  • 也许将每个唯一坐标作为您正在寻找的简单解决方案。它确实没有合并,但它只会显示不同的行,您可以在之后绘制它们。你可以这样做:A &lt;- unique(A)
  • @Newl,我已经尝试过你的建议。节点集是对的,但边的顺序不对。
  • 哦,我明白了。如果您觉得可以,您可以使用 delete_vertices() 手动删除额外的节点。要查找索引,您必须使用 which(duplicated(A)). 找到重复项的索引

标签: r merge igraph


【解决方案1】:

跟进我的评论,并通过进一步调查,我设法减少了您的图表。这不是微不足道的,因为我必须通过 ID 向量明确告诉 igraph 我要合并哪些节点,即:如果您有四个 ID 为 c(1,2,3,4) 的节点并且您想合并第一个其中三个,你必须给出以下 id 向量:c(1,1,1,2)。

我也使用了 data.table 库,因为我更熟悉它的语法。

我使用的代码:

dt <- as.data.table(A)
groupID <- dt[,.(gID = .GRP),by = list(dt$V1,dt$V2)]
colnames(dt) <- c('X','Y')
colnames(groupID) <- c('X','Y','gid')

dt[groupID, gID := i.gid, on = c(X = 'X', Y = 'Y')]

plot(contract.vertices(g,dt$gID),layout = as.matrix(groupID))

我将给定的 m 矩阵转换为 data.table,然后为组标识符创建了另一个 dt (data.table),因此您有一个单独的 id对于每个组,由坐标的唯一组合创建(每个 [-2,0] 有一个 id,每个 [0,0] 有一个 id,等等)

所以 groupID dt 看起来像这样:

     X  Y gid
 1:  0  0   1
 2:  1  0   2
 3:  1 -1   3
 4:  1 -2   4
 5:  0 -2   5
 6: -1 -2   6
 7: -2 -2   7
 8: -2 -1   8
 9: -1 -1   9
10:  0 -1  10
11:  0 -3  11
12:  0 -4  12
13: -1 -4  13
14: -1 -3  14
15:  2 -2  15
16:  2 -3  16
17:  1 -3  17

在此之后,我刚刚重命名了列以进行进一步的转换。

下一步是将这两个 dts 加入到它们共享的 XY 列上,我刚刚给了一个新名称。

dt 现在看起来像这样:

     X  Y gID
 1:  0  0   1
 2:  1  0   2
 3:  1 -1   3
 4:  1 -2   4
 5:  0 -2   5
 6: -1 -2   6
 7: -2 -2   7
 8: -2 -1   8
 9: -1 -1   9
10:  0 -1  10
11:  0 -2   5
12:  0 -3  11
13:  0 -4  12
14: -1 -4  13
...

最后一步是通过 contract.vertices 函数按节点的 id 合并节点。合并dt的gID属性必须作为属性给出,所以它知道哪些节点必须被合并。 (您可以将其分配给您的 g 变量 ofc。)

幸运的是,groupID dt 包含正确的绘图布局,因为它具有组(您的坐标)及其 ID。

现在节点已经合并了,但是合并后的顶点到它们的邻居之间还有多条边,之后要删除。

转换后的图形如下所示:

对应帖子:

【讨论】:

  • 感谢您的调查。我已经手动删除了边缘:g
  • @Nick 如果边的方向不重要,那么您可以轻松simplify() 图,但是如果方向很重要,那么您必须定义用于删除它们的规则。您可以考虑只保留起始节点的 id 小于结束节点的边的条件。
  • 我的图表很简单。我认为 as.undirected() 函数可以帮助我。
猜你喜欢
  • 2020-01-21
  • 1970-01-01
  • 2013-09-30
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多