我想使用 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
输出显示节点A
、B
、C
和D
在最短路径上,但没有显示节点的顺序是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
然而,由于多种原因,这并不优雅。
node_id
中包含的信息丢失,所以我必须手动进行映射“B”->“2”,“C”->“3 " 或者编写更复杂的代码来连接来自节点和边缘数据的信息。"B" "A" "D" "C"
,而不是 2 1 4 3
。是否有一些直接的方法可以直接使用 tidygraph 获取沿最短路径的节点序列?
答案 0 :(得分:2)
编辑:可以使用任何名称作为 node_key
参数,这将导致成功构建 tbl_graph
。但是,将其传递给 igraph
函数仅在节点数据中的列被称为 name
时才有效。这可能是需要向 tidygraph
报告的问题。
可以通过使用 tidygraph
函数直接使用 igraph
执行此操作,请考虑以下事项:
tbl_graph
对象是 igraph
的子类,因此无需将您的数据转换为 tibble,然后从数据框中转换为 igraph,您可以直接将 igraph 函数运行到 {{1} } 对象。tbl_graph
参数。这被传递到 node_key
并因此存储在其属性中。但是,像您在示例中所做的那样使用 igraph
将不起作用,因为 node_id
在内部对节点索引使用相同的名称,因此会以某种方式被覆盖。因此,如果您调用不同于“node_id”的节点键列,则可以将其设置为 igraph
参数。node_key
,应该可以将列名作为 tidygraph
传递,请参阅 here。node_key 节点中的列的名称,该列的字符代表列和来自列的字符应与之匹配。如果 NA 总是选择第一列。如果 to 和 from 以整数形式给出,则此设置无效。
如果带有 ID 的列名为 node_key
,那么 name
也会识别它,并在调用 igraph
函数时返回命名路径。但是,当将任何其他节点列作为 shortest_paths()
传递时,这似乎会失败,因此对于此示例,我们可以调用列 node_key
。
请参阅下面的相同代码,并在构造过程中进行了这些修改,以及您要求的输出。
name