如何使用igraph将两个节点合并为一个节点

时间:2013-09-25 06:29:15

标签: r igraph

我试图将图(G)中的两个节点(称为'V'和'U')合并为一个节点(V)。

G是779个节点(网站)的超链接网络。每条边代表一个超链接。 V和U实际上是同一个网站,但不幸的是,该网站的网页已分成两个独立的节点。所以我想把它们放回一个节点。

我已经研究过contract.vertices函数,但我无法理解如何在这里进行调整。

以下是我的图表(G)的属性。

> G
IGRAPH D--- 779 3544 -- 
+ attr: Image File (v/c), Ringset (v/n), Country Code TLD (v/n), Generic TLD (v/n), Number of Pages (v/n), Categorical 1 (v/n), Categorical 2 (v/n),
  Categorical 3 (v/n), id (v/c), label (v/c), Width (e/n)

我有两个要合并的节点:

> V(g)$id[8]
[1] "http://www.police.uk/"

> V(g)$id[14]
[1] "http://police.uk/"

图中共有779个节点和3544个边。

我希望这两个节点成为图中的单个节点(即它们将具有相同的“id”)。现在,来自/到其他节点的所有链接和外链都将仅指向这个新的单个节点。

所有其他属性将保持不变,但Number of Pages除外(此值将是合并之前两个节点的总和)。

1 个答案:

答案 0 :(得分:12)

contract.vertices确实是正确的尝试功能,但它的API有点复杂,因为它的设计不仅可以合并一对节点,而且可以在一次通过中合并多对。 (它也可以置换顶点)。为此,它需要从旧顶点ID到新顶点ID的映射

如果您不熟悉顶点ID:igraph使用1到N范围内的整数标识图形的每个顶点,其中N是顶点数。 contract.vertices所需的映射必须是长度为N的列表,其中列表的第i个元素包含与之前的ID 对应的节点的 new ID >合并。

假设您的图表包含10个节点。以下映射向量将简单地将每个节点映射到它已有的相同ID,因此它不会进行任何合并:

c(1,2,3,4,5,6,7,8,9,10)

现在,假设您要将节点7合并到节点4.您必须告诉igraph节点7的 new ID将为4,因此您必须更改第7个元素以上向量到4:

c(1,2,3,4,5,6,4,8,9,10)

这将差不多完成工作;问题是igraph要求节点ID在1到N的范围内,并且由于你仍然有一个ID为10的节点,根据上面的映射,igraph不会删除旧节点7。你在收缩顶点后,可以使用delete.vertices手动删除它,也可以指定不同的映射,不仅将节点7合并到节点4,还将节点8的ID更改为7,节点9更改为8和节点10到9:

c(1,2,3,4,5,6,4,7,8,9)

现在,由于您还希望新节点的Number of Pages属性是两个旧节点的值的总和,您必须告诉igraph在合并期间如何处理顶点属性。 vertex.attr.comb contract.vertices参数用于此目的。在您的情况下,vertex.attr.comb的值应该是这样的:

list("Number of Pages"="sum", "first")

其中"Number of Pages"="sum"表示Number of Pages属性的新值应通过对旧属性值求和来计算,"first"表示对于此处未提及的所有其他属性,新值value应该由合并为单个节点的节点集合中的第一个节点的旧值确定。有关此参数格式的更多详细信息,请参阅R中的?attribute.combination