所以,我有一个多个tidygraph
对象的列表,我想要做的是返回索引一个特定的tidygraph
对象,由用户选择。希望我下面的例子能解释这个问题。
(旁白:我尝试了一个我在下面展示的解决方案,但目前运行速度非常慢。我希望提出一个不同的、更快的解决方案。)
首先,我创建一些数据以转换为tidygraph
对象,然后创建tidygraph
对象并将它们全部放在一个列表中:
library(tidygraph)
# create some data for the tbl_graph
nodes <- data.frame(name = c("Hadley", "David", "Romain", "Julia"),
level = c(1,1,1,1),
rank = c(1,1,1,1))
nodes1 <- data.frame(name = c("Hadley", "David", "Romain", "Julia"),
level = c(1,1,1,1),
rank = c(2,2,2,2))
nodes2 <- data.frame(name = c("Hadley", "David", "Romain", "Julia"),
level = c(1,1,1,1),
rank = c(3,3,3,3))
nodes3 <- data.frame(name = c("Hadley", "David", "Romain", "Julia"),
level = c(2,2,2,2),
rank = c(1,1,1,1))
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))
# create the tbl_graphs
tg <- tbl_graph(nodes = nodes, edges = edges)
tg_1 <- tbl_graph(nodes = nodes1, edges = edges)
tg_2 <- tbl_graph(nodes = nodes2, edges = edges)
tg_3 <- tbl_graph(nodes = nodes3, edges = edges)
# put into list
myList <- list(tg, tg_1, tg_2, tg_3)
为清楚起见,查看第一个列表元素如下所示:
> myList[1]
[[1]]
# A tbl_graph: 4 nodes and 9 edges
#
# A directed simple graph with 1 component
#
# Node Data: 4 × 3 (active)
name level rank
<chr> <dbl> <dbl>
1 Hadley 1 1
2 David 1 1
3 Romain 1 1
4 Julia 1 1
#
# Edge Data: 9 × 2
from to
<int> <int>
1 1 2
2 1 3
3 1 4
# … with 6 more rows
我们可以看到每个对象都有一个名为的变量level
和另一个名为的变量rank
。我试图做的是通过选择level
和rank
数字返回对象的列表索引。因此,例如,如果我选择level = 1
and rank = 2
,我的函数将返回具有这些值的对象的索引(在本例中为第二个列表元素)。我尝试的解决方案如下,但这是一个非常缓慢的过程......我想知道是否有更好的方法来实现我想要的?
我尝试的解决方案
在我的解决方案中,我首先将每个tidygraph
对象都放在一个小标题中,以使它们更易于操作。这就是为什么我的功能如此缓慢的原因。在我的数据tidygraph
中,一个列表中最多可以有 200,000 个对象,因此遍历它们并将它们全部转换为小标题是一个非常缓慢的过程。我这样做是这样的:
# seperating out the list to make it easier to manipulate
list_obj <- lapply(myList, function(x){
edges <- tidygraph::activate(x, edges) %>% tibble::as_tibble()
nodes <- tidygraph::activate(x, nodes) %>% tibble::as_tibble()
return(list(edges = edges, nodes = nodes))
} )
然后这是我实际用来提取所选对象索引的函数:
# this function returns the tree index asked for by user
getTreeListNumber <- function(listObj, level, rank){
res <- 0
listNumber <- NA
for(i in 1:length(listObj)){
res <- level %in% listObj[[i]]$nodes$level && rank %in% listObj[[i]]$nodes$rank
if(res == TRUE){
listNumber <- i
}
}
return(listNumber)
}
例如:
> getTreeListNumber(list_obj, level = 1, rank = 2)
[1] 2
通过选择级别和排名,该函数返回列表中的对象索引。但是有没有更快的方法来达到这个结果?