фильтр в тидиографе - PullRequest
2 голосов
/ 18 июня 2019

Рассмотрим этот простой пример

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

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Одно из возможных решений - преобразовать ваши данные в subgraph и отфильтровать их по id:

Создать subgraph и filter по id:

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, но это не самый простой подход, потому что вы сначала должны определить id, которые включены в power 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()

enter image description here

Примечание

Обратите внимание, что преобразование в data.frame изменит ваше id имя переменной, чтобы вы могли изменить его снова с помощью rename.

0 голосов
/ 19 июня 2019

на самом деле очень простое решение

activate(nodes) %>% 
  filter(!node_is_isolated())
...