如何从 R 中的 tidygraph 对象列表中操作 tidygraph 对象?
How to manipulate a tidygraph object from a list of tidygraph objects inR?
如果我有一个 tidygraph 对象列表,我想根据某些条件删除列表元素。例如,如果我有一个整洁的图形对象列表,如下所示:
nodes <- data.frame(name = c("Hadley", "David", "Romain", "Julia"))
edges <- data.frame(from = c(1, 1, 1, 2, 3, 3, 4, 4, 4),
to = c(2, 3, 4, 1, 1, 2, 1, 2, 3))
nodes_1 <- data.frame(name = c(NA))
edges_1 <- c()
tg <- tbl_graph(nodes = nodes, edges = edges)
tg_1 <- tbl_graph(nodes = nodes_1, edges = edges_1)
myList <- list(tg, tg_1)
查看 myList
的输出,我们可以看到其中一个 tidygraph 对象没有与之关联的边,并且 names
列是 NA
.
> myList
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 × 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 × 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# … with 6 more rows
[[2]]
# A tbl_graph: 1 nodes and 0 edges
#
# A rooted tree
#
# Node Data: 1 × 1 (active)
name
<lgl>
1 NA
#
# Edge Data: 0 × 2
# … with 2 variables: from <int>, to <int>
我想知道是否有一种方法可以遍历列表并检查是否有任何 tidygraph 对象没有边缘数据或者是 NA
(如上例所示)并从中删除该对象列表。
我知道我可以使用 myList <- myList[-2]
手动删除列表。但是当我的列表中有大量 tidygraph 对象时,我一直在寻找更通用的解决方案?
我们可以
library(purrr)
library(tibble)
library(dplyr)
keep(myList, ~ .x %>%
as_tibble %>%
pull(name) %>%
is.na %>%
`!` %>%
any)
-输出
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 x 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 x 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# … with 6 more rows
您可以使用 igraph::gsize()
过滤列表,其中 returns 边数:
library(tidygraph)
library(igraph)
Filter(function(x) gsize(x) > 0, myList) # Filter(gsize, myList) also works but potentially less safe.
# Or
purrr::discard(myList, ~ gsize(.x) == 0)
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 x 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 x 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# ... with 6 more rows
如果我有一个 tidygraph 对象列表,我想根据某些条件删除列表元素。例如,如果我有一个整洁的图形对象列表,如下所示:
nodes <- data.frame(name = c("Hadley", "David", "Romain", "Julia"))
edges <- data.frame(from = c(1, 1, 1, 2, 3, 3, 4, 4, 4),
to = c(2, 3, 4, 1, 1, 2, 1, 2, 3))
nodes_1 <- data.frame(name = c(NA))
edges_1 <- c()
tg <- tbl_graph(nodes = nodes, edges = edges)
tg_1 <- tbl_graph(nodes = nodes_1, edges = edges_1)
myList <- list(tg, tg_1)
查看 myList
的输出,我们可以看到其中一个 tidygraph 对象没有与之关联的边,并且 names
列是 NA
.
> myList
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 × 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 × 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# … with 6 more rows
[[2]]
# A tbl_graph: 1 nodes and 0 edges
#
# A rooted tree
#
# Node Data: 1 × 1 (active)
name
<lgl>
1 NA
#
# Edge Data: 0 × 2
# … with 2 variables: from <int>, to <int>
我想知道是否有一种方法可以遍历列表并检查是否有任何 tidygraph 对象没有边缘数据或者是 NA
(如上例所示)并从中删除该对象列表。
我知道我可以使用 myList <- myList[-2]
手动删除列表。但是当我的列表中有大量 tidygraph 对象时,我一直在寻找更通用的解决方案?
我们可以
library(purrr)
library(tibble)
library(dplyr)
keep(myList, ~ .x %>%
as_tibble %>%
pull(name) %>%
is.na %>%
`!` %>%
any)
-输出
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 x 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 x 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# … with 6 more rows
您可以使用 igraph::gsize()
过滤列表,其中 returns 边数:
library(tidygraph)
library(igraph)
Filter(function(x) gsize(x) > 0, myList) # Filter(gsize, myList) also works but potentially less safe.
# Or
purrr::discard(myList, ~ gsize(.x) == 0)
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 x 1 (active)
name
<chr>
1 Hadley
2 David
3 Romain
4 Julia
#
# Edge Data: 9 x 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# ... with 6 more rows