4

考虑这个简单的例子

library(tidygraph)

mynodes <- tibble(id = c(1,2,3,4,5))

myedges <- tibble(from = c(1,1,1,5),
                  to = c(1,2,3,4),
                  power = c(10,10,10,3))

tbl_graph(nodes = mynodes, edges = myedges)
# A tbl_graph: 5 nodes and 4 edges
#
# A directed multigraph with 2 components
#
# Node Data: 5 x 1 (active)
     id
  <dbl>
1     1
2     2
3     3
4     4
5     5
#
# Edge Data: 4 x 3
   from    to power
  <int> <int> <dbl>
1     1     1    10
2     1     2    10
3     1     3    10
# ? with 1 more row

我知道我可以filter用来轻松过滤节点或边缘。

我的问题是如何根据边缘上的条件过滤节点。

例如运行:

mygraph %>% activate(edges) %>% filter(power == 3)

仍然会返回所有节点,这在绘图时很烦人(这些节点将没有边!)。

如何保留与过滤后的边集连接的所有节点?

# A tbl_graph: 5 nodes and 1 edges
#
# A rooted forest with 4 trees
#
# Edge Data: 1 x 3 (active)
   from    to power
  <int> <int> <dbl>
1     5     4     3
#
# Node Data: 5 x 1
     id
  <dbl>
1     1
2     2
3     3
# ? with 2 more rows
4

3 回答 3

3

一种可能的解决方案是将您的数据转换为subgraph并通过以下方式过滤id

创建一个subgraphfilterid

sub_mygraph <- to_subgraph(mygraph, id %in% c(4, 5), subset_by = "nodes")$subgraph 

sub_mygraph
# A tbl_graph: 2 nodes and 1 edges
#
# A rooted tree
#
# Node Data: 2 x 1 (active)
     id
  <dbl>
1     4
2     5
#
# Edge Data: 1 x 3
   from    to power
  <int> <int> <dbl>
1     2     1     3

或者,您可以将数据转换为data.frame并按 过滤power,然后再转换tbl_graph回。

转换为data.frame

library(tidygraph)

mygraph %>% igraph::as_data_frame() %>% 
  filter(power == 3) %>% 
  as_tbl_graph()

# A tbl_graph: 2 nodes and 1 edges
#
# A rooted tree
#
# Node Data: 2 x 1 (active)
  name 
  <chr>
1 5    
2 4    
#
# Edge Data: 1 x 3
   from    to power
  <int> <int> <dbl>
1     1     2     3

或者您可以按 过滤id,但这不是最直接的方法,因为您首先必须确定 3 中id包含的内容power

mygraph %>% filter(id %in% c(5, 4))

# A tbl_graph: 2 nodes and 1 edges
#
# A rooted tree
#
# Node Data: 2 x 1 (active)
     id
  <dbl>
1     4
2     5
#
# Edge Data: 1 x 3
   from    to power
  <int> <int> <dbl>
1     2     1     3

现在您可以在没有烦人的节点的情况下绘制它:

library(ggraph)

mygraph %>% igraph::as_data_frame() %>% 
  filter(power == 3) %>% 
  as_tbl_graph () %>% 
  rename(id = name) %>% 
  ggraph() +
  geom_edge_fan() +
  geom_node_point(aes(color = id)) +
  theme_graph()

在此处输入图像描述

笔记

请注意,转换为data.frame将更改您的id变量名称,因此您可以使用 再次更改它rename

于 2019-06-18T07:43:26.147 回答
0

实际上有一个非常简单的解决方案

activate(nodes) %>% 
  filter(!node_is_isolated())
于 2019-06-19T13:45:04.583 回答
0

您可以使用 .E() & .N() fcns 访问节点或边,而另一个在 tidygraph 中激活

此处的介绍中提到了这一点: https ://www.data-imaginist.com/2017/introducing-tidygraph/

因此,要根据边缘属性过滤到节点,您可以在激活节点时使用 .E() 函数:

mygraph %>%
  activate("nodes") %>%
  filter(.E()$power[id] == 3)
于 2021-06-04T15:30:26.220 回答