在 tidygraph 中过滤
filter in a tidygraph
考虑这个简单的例子
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)
仍然 returns 所有 节点,这在绘图时很烦人(这些节点将没有边!)。
如何保留与我过滤的边集连接的所有节点?
# 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
一种可能的解决方案是将您的数据转换为 subgraph
并按 id
:
过滤
通过 id
创建 subgraph
和 filter
:
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
进行筛选,但这不是最直接的方法,因为您首先必须确定 power
中包含的 id
3:
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
再次更改它。
其实有一个很简单的解决方法
activate(nodes) %>%
filter(!node_is_isolated())
您可以使用 .E() 和 .N() fcns 访问节点或边,而另一个在 tidygraph 中被激活
这里的介绍中提到了这一点:
https://www.data-imaginist.com/2017/introducing-tidygraph/
因此,要根据边属性过滤到节点,您可以在激活节点时使用 .E() 函数:
mygraph %>%
activate("nodes") %>%
filter(.E()$power[id] == 3)
考虑这个简单的例子
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)
仍然 returns 所有 节点,这在绘图时很烦人(这些节点将没有边!)。
如何保留与我过滤的边集连接的所有节点?
# 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
一种可能的解决方案是将您的数据转换为 subgraph
并按 id
:
通过 id
创建 subgraph
和 filter
:
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
进行筛选,但这不是最直接的方法,因为您首先必须确定 power
中包含的 id
3:
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
再次更改它。
其实有一个很简单的解决方法
activate(nodes) %>%
filter(!node_is_isolated())
您可以使用 .E() 和 .N() fcns 访问节点或边,而另一个在 tidygraph 中被激活
这里的介绍中提到了这一点: https://www.data-imaginist.com/2017/introducing-tidygraph/
因此,要根据边属性过滤到节点,您可以在激活节点时使用 .E() 函数:
mygraph %>%
activate("nodes") %>%
filter(.E()$power[id] == 3)