从tidygraph中提取特定节点的邻域/子图

5

对于某些在igraph中相对简单的Tidygraph操作,我有些困惑。

特别是我想要分析不同级别的特定邻域。我认为我需要使用Morphs来实现这一点,但我还没有做到。

library(tidygraph)
library(ggraph)

net <- tibble::tibble(A = letters[1:6],
               B = rep(c("x", "y"), each = 3)) %>% 
  tidygraph::as_tbl_graph()

例如,假设我有以下网络结构:

我想分析关于x的邻域。

net %>% 
  ggraph(layout = "nicely") +
    geom_edge_link() +
    geom_node_point(size = 10, fill = "white", shape = 21) +
    geom_node_text(aes(label = name)) +
    theme_graph()

iGraph的实现方法如下:

提取节点x的邻域。

Full network

v <- net %>% 
  tidygraph::as.igraph() %>% 
  igraph::neighborhood(nodes = "x", order = 1)

通过取消igraph.vs对象的列表构建子图

igraph::induced_subgraph(net, vids = unlist(v)) %>% 
  tidygraph::as_tbl_graph() %>% 
  ggraph(layout = "nicely") +
    geom_edge_link() +
    geom_node_point(size = 10, fill = "white", shape = 21) +
    geom_node_text(aes(label = name)) +
    theme_graph()

如何使用tidygraph实现这个功能?

以下实现返回相同的错误:

期望的邻域

net %>% 
  tidygraph::morph(to_local_neighborhood, node = "x", order = 1, mode = "all")

net %>% 
  to_local_neighborhood(node = "x", order = 1, mode = "all")

Error in if (is.numeric(v) && any(v < 0)) { : missing value where TRUE/FALSE needed

1
似乎你需要通过位置而不是名称来指定节点。在你的例子中,节点x是第7个。目前我没有找到更好的方法,只能通过筛选节点、提取位置并使用该位置获取子图。你也可以使用类似于dplyr的函数filternode_is_adjacent - camille
@camille 很不幸。虽然 node_is_adjacent 对于这种用例可以工作(尽管我还没有测试过)。但似乎这个解决方案对于大于1的顺序是行不通的(例如,要获取邻居的邻居)。 - user131291
1
可能有更好的方法,不确定。为什么不直接使用 igraph 函数呢?在 tidygraph 类和 igraph 类之间切换似乎很容易。 - camille
如果将来有人发现此内容,请参考此Github问题获取更多解决方案的详细信息。我会尽快发布最终解决方案。 - user131291
1个回答

4
有一种使用一些基本的 R 函数的方法,比起 GitHub 的解决方案 来说稍微绕一些路,以防您对 tidygraph API 不是很熟悉。但是我们可以使用 @camille 的见解 来获取节点的索引,因为它要求 node 参数必须是一个数字。
library(tidygraph)
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(ggraph)
#> Loading required package: ggplot2

# Example
net <- tibble::tibble(A = letters[1:6],
                      B = rep(c("x", "y"), each = 3)) %>% 
  tidygraph::as_tbl_graph()

# Get row name index as integer because tidygraph requirement
node_tbl <- data.frame(activate(net, nodes))  # Make sure focus on nodes
node_idx <- rownames(node_tbl)[node_tbl$name == "x"]
node_idx <- as.integer(node_idx)  # tidygraph needs it as number, not string

net %>%
  tidygraph::convert(to_local_neighborhood,
                     node = node_idx,
                     order = 1,
                     mode = "all") %>%
  ggraph(layout = "nicely") +
  geom_edge_link() +
  geom_node_point(size = 10, fill = "white", shape = 21) +
  geom_node_text(aes(label = name)) +
  theme_graph()

reprex package (v0.3.0) 于2020年07月03日创建

以下是利用 tidygraph API 的 GitHub 链接解决方案,通过在转换中使用 .N() 来引用节点表中的 which(.N()$name == "x")

library(tidygraph)
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(ggraph)
#> Loading required package: ggplot2

# Example
net <- tibble::tibble(A = letters[1:6],
                      B = rep(c("x", "y"), each = 3)) %>% 
  tidygraph::as_tbl_graph()

net %>%
  tidygraph::convert(to_local_neighborhood,
                     node = which(.N()$name == "x"),
                     order = 1,
                     mode = "all") %>%
  ggraph(layout = "nicely") +
  geom_edge_link() +
  geom_node_point(size = 10, fill = "white", shape = 21) +
  geom_node_text(aes(label = name)) +
  theme_graph()

创建于2020年7月3日,使用reprex包(v0.3.0)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接