【问题标题】:igraph in R - merging two graphsR中的igraph - 合并两个图
【发布时间】:2017-09-09 03:50:13
【问题描述】:

我正在尝试使用 igraph 合并 R 中的两个图表。理想情况下,我会从g1g2 创建一个顶点联合,只保留g1 的边。该联合应基于label 属性创建。我想我可以在合并之前简单地从g2 中删除所有边缘,使用类似这样的东西:

g2 %>% delete_edges(seq(1, length(E(g2)), by = 1))

不过,当我创建这样的联合时:

g.union <- graph.union(g1, g2, byname=F)

我得到一个带有属性的图表 id_1id_2label_1label_2weight_1weight_2... 这不是我想要的。我需要保留g1 中的所有顶点和边,仅添加g2g1 中缺少的那些顶点。保留这些添加的顶点的所有属性。

任何帮助表示赞赏!

编辑:

@MrFlick,我不能分享这些图表,但一个简单的例子是这样的:

我有g1

graph
[
  directed 1
  node
  [
    id 1
    label "it2igcryfm862x"
    mydetails "somedetails1"
  ]
  node
  [
    id 2
    label "it0l2xa53eu1w3"
    mydetails "somedetails2"
  ]
  node
  [
    id 3
    label "iszyxcopnao380"
    mydetails "somedetails3"
  ]
 edge
  [
    source 1
    target 2
    weight 1
  ]
  edge
  [
    source 1
    target 3
    weight 2
  ]
  edge
  [
    source 2
    target 3
    weight 1
  ]
]

g2

graph
[
  directed 1
  node
  [
    id 1
    label "it2igcryfm862x"
    mydetails "somedetails1"
  ]
  node
  [
    id 2
    label "it0l2xa53eu1w3"
    mydetails "somedetails2"
  ]
  node
  [
    id 3
    label "iszyxcopnao380"
    mydetails "somedetails3"
  ]
  node
  [
    id 4
    label "it0lhztmkln4n6"
    mydetails "somedetails4"
  ]
 edge
  [
    source 1
    target 2
    weight 1
  ]
  edge
  [
    source 1
    target 3
    weight 3
  ]
  edge
  [
    source 2
    target 3
    weight 2
  ]
  edge
  [
    source 2
    target 4
    weight 2
  ]
  edge
  [
    source 3
    target 4
    weight 1
  ]
]

而我需要的是g3

graph
[
  directed 1
  node
  [
    id 1
    label "it2igcryfm862x"
    mydetails "somedetails1"
  ]
  node
  [
    id 2
    label "it0l2xa53eu1w3"
    mydetails "somedetails2"
  ]
  node
  [
    id 3
    label "iszyxcopnao380"
    mydetails "somedetails3"
  ]
  node
  [
    id 4
    label "it0lhztmkln4n6"
    mydetails "somedetails4"
  ]
 edge
  [
    source 1
    target 2
    weight 1
  ]
  edge
  [
    source 1
    target 3
    weight 2
  ]
  edge
  [
    source 2
    target 3
    weight 1
  ]
]

【问题讨论】:

  • 如果您向reproducible example 提供示例输入数据和所需输出,会更容易为您提供帮助。
  • 试图提供三个简单的图表,以便更好地了解问题所在。
  • 您需要在reproducible format 中提供数据。应该如何在 R 中加载这些数据?

标签: r graph igraph unions


【解决方案1】:

这是一个可重现的例子

library(igraph)
set.seed(1)
g1 <- make_(ring(10), with_vertex_(label = LETTERS[1:10]))
V(g1)$color = "red"
g2 <- make_(ring(15), with_vertex_(label = LETTERS[1:15]))
V(g2)$color <- "cyan"

你需要

保留 g1 中的所有顶点和边,仅添加这些顶点 来自 g2 中缺少的 g1。保留添加的所有属性 顶点。

一种方法:

v <- V(g2)[!V(g2)%in%V(g1)]
g3 <- add_vertices(g1, length(v), attr = vertex.attributes(g2, v))

这是两个原始图表和结果的样子:

par(mfrow=c(1,3))
lapply(mget(ls(pattern = "^g\\d")), plot)

【讨论】:

  • 旁注:如果来自 g1 和 g2 的属性不同,则可能需要g3 &lt;- add_vertices(g1, length(v), attr = vertex.attributes(g2, v)[intersect(vertex_attr_names(g1), vertex_attr_names(g2))]),并且需要 g2 中也在 g1 中的那些...
  • 非常感谢 lukeA 和 @G5W。我在这里似乎缺少一些东西,因为我收到了这个错误:Error in vertex.attributes(g2, v) : object 'value' not found
  • @Srecko 我无法重现该错误,因为您仍然没有提供可重现的示例。如果需要,有两个人已经向您指出了该信息。请阅读并相应地编辑您的帖子。目标应该是任何人都可以通过复制粘贴来运行代码,就像 G5W 的答案一样。
  • 谢谢@lukeA,但我使用的是您提供的代码。刚刚复制并尝试运行,但出现此错误。
  • 就是这样,@lukeA。问题出在 igraph 库上。它适用于版本 1.1.2。非常感谢!
【解决方案2】:

您的原始代码似乎接近您提供的示例。

library(igraph)

###  Recreating your example
par(mfrow = c(2,2), mar=c(0.5,0.5,0.5,0.5))
g1 = graph_from_edgelist(matrix(c(1,2,1,3,2,3), ncol=2, byrow=TRUE))
g1 = set_vertex_attr(g1, "label", 
    value=c("it2igcryfm862x", "it0l2xa53eu1w3", 
        "iszyxcopnao380"))
plot(g1)
box()

g2 = graph_from_edgelist(matrix(c(1,2,1,3,2,3,2,4,3,4), ncol=2, byrow=TRUE))
g2 = set_vertex_attr(g2, "label", 
    value=c("it2igcryfm862x", "it0l2xa53eu1w3", 
        "iszyxcopnao380", "it0lhztmkln4n6"))
plot(g2)
box()

## Create the desired union
g1g2 = union(g1,delete_edges(g2, E(g2)))

## Edit: Preserving labels
NewLabels = c(vertex_attr(g1, "label"), 
    setdiff(vertex_attr(g2, "label"), vertex_attr(g1, "label")))
g1g2 = set_vertex_attr(g1g2, "label", value=NewLabels)

plot(g1g2)
box()

【讨论】:

  • 谢谢,G5W!这个确实按预期返回了所有节点和边。但是,每个属性都是重复的。在您提供的示例中,它将是 attr: label_1 (v/c), label_2 (v/c),而不是 label
  • 是的,我发现我丢失了 union 中的标签。编辑答案。
  • 要么我做错了,要么我们得到相同的属性 3 次 :) 我认为这没什么大不了的,但是当你运行 vertex_attr(g1g2, index = V(g1g2)) 时,这就是你的会得到:$label_1 [1] "it2igcryfm862x" "it0l2xa53eu1w3" "iszyxcopnao380" NA $label_2 [1] "it2igcryfm862x" "it0l2xa53eu1w3" "iszyxcopnao380" "it0lhztmkln4n6" $label [1] "it2igcryfm862x" "it0l2xa53eu1w3" "iszyxcopnao380" "it0lhztmkln4n6"
  • 你没有做错任何事。 union 操作将标签从 g1 复制到新属性 label_1。来自 g2 的标签转到 label_2。我创建了一个新的标签属性,以便正确标记图片。您可以删除多余的 label_1 和 label_2。
  • 当然,有道理。谢谢!
最近更新 更多