2

我想使用tidygraph获取两个节点之间最短路径的节点序列。考虑这个例子。

library(tidygraph)
library(tidyverse)
demo_netw <- tbl_graph(nodes = tibble(node_id = c("A", "B", "C", "D")),
                       edges = tribble(~from, ~to,
                                       "B", "A",
                                       "D", "C",
                                       "A", "D"))
shortest_path_from_B_to_C <-
  demo_netw %>%
  convert(to_shortest_path, node_id == "B", node_id == "C")
shortest_path_from_B_to_C

## # A tbl_graph: 4 nodes and 3 edges
## #
## # A rooted tree
## #
## # Node Data: 4 x 2 (active)
##   node_id .tidygraph_node_index
##   <chr>                   <int>
## 1 A                           1
## 2 B                           2
## 3 C                           3
## 4 D                           4
## #
## # Edge Data: 3 x 3
##    from    to .tidygraph_edge_index
##   <int> <int>                 <int>
## 1     2     1                     1
## 2     4     3                     2
## 3     1     4                     3

输出显示节点ABCD位于最短路径上,但未显示节点序列为B -> A -> D -> C。返回的边缘数据也不显示边缘的顺序。

我知道我可以用 igraph 完成这样的任务。

library(igraph)
demo_igraph <-
  demo_netw %>%
  activate(edges) %>%
  as_tibble() %>%
  graph_from_data_frame()

# We cannot easily access the node_id column, so we must manually make the
# mapping "B" -> "2", "C" -> "3"
shortest_paths(demo_igraph, "2", "3")$vpath

## [[1]]
## + 4/4 vertices, named, from a854191:
## [1] 2 1 4 3

然而,由于几个原因,这是不优雅的。

  • 我正在寻找一种不求助于其他软件包的 tidygraph 解决方案。
  • 导出 tidygraph 边缘数据时,节点数据列node_id中包含的信息丢失了,所以我必须手动进行映射“B”->“2”,“C”->“3”,或者编写更精细的代码加入来自节点和边缘数据的信息。
  • 我希望输出是"B" "A" "D" "C",不是2 1 4 3

有没有一些直接的方法可以直接用tidygraph获取最短路径上的节点序列?

4

1 回答 1

2

编辑:可以使用任何名称作为node_key参数,这将导致成功构建tbl_graph. 但是,仅当在节点数据igraph中调用该列时,将其传递给函数才有效。name这可能是需要向 报告的问题tidygraph

tidygraph考虑以下因素,可以通过使用igraph函数直接使用 来执行此操作:

  1. tbl_graph对象子类,igraph因此无需将数据转换为 tibble,然后从数据帧转换为 igraph,您可以直接将 igraph 函数运行到tbl_graph对象。
  2. node_key构建图形时可以设置参数。这被传递igraph并因此存储在其属性中。但是,node_id像您在示例中所做的那样使用将不起作用,因为在igraph内部使用相同的名称作为节点索引,因此会以某种方式被覆盖。因此,如果您调用与“node_id”不同的节点键列,则可以将其设置为node_key参数。
  3. 根据tidygraph应该可以将列名作为 a 传递node_key,请参见此处

node_key节点中的列名称,表示与列之间的字符应与之匹配。如果 NA 始终选择第一列。如果 to 和 from 以整数形式给出,则此设置无效。

如果带有 ID 的列被调用name,那么它也被 识别igraph,并且在调用shortest_paths()函数时将返回命名路径。但是,当将任何其他节点列作为 a 传递时,这似乎失败了node_key,因此对于此示例,我们可以调用该列name

请参阅下面的相同代码,在构建过程中进行了一些修改,以及您要求的输出。

library(tidygraph)
library(tidyverse)
library(igraph)

demo_netw <- tbl_graph(nodes = tibble(name = c("A", "B", "C", "D")),
                       edges = tribble(~from, ~to,
                                       "B", "A",
                                       "D", "C",
                                       "A", "D"))

shortest_paths(demo_netw, "B", "C")$vpath
#> [[1]]
#> + 4/4 vertices, named, from e00d5b2:
#> [1] B A D C
于 2020-12-28T16:48:34.010 回答