因此,我有一个多个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)为了清晰起见,查看第一个list元素如下所示:
> 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和rank = 2,我的函数将返回带有这些值的对象的索引(在本例中是第二个list元素)。我尝试的解决方案如下,但这是一个非常缓慢的过程.我想知道是否有更好的方法来实现我想要的?
我尝试的解决方案
在我的解决方案中,我首先把每个tidygraph对象都转到一个tibble中,以使它们更易于操作。这就是为什么我的功能这么慢。在我的数据中,我可以在一个列表中包含多达200000个tidygraph对象,因此遍历它们并将它们全部转换为tibbles是一个非常缓慢的过程。我是这样做的:
# 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通过选择级别和级别,函数返回列表中的对象索引。但是,是否有更快的方法来实现这一结果?
发布于 2021-10-28 01:59:31
你可以试试-
getTreeListNumber <- function(listObj, level, rank){
which(sapply(myList, function(x) {
nodes <- tidygraph::activate(x, nodes) %>% tibble::as_tibble()
all(nodes$level == level & nodes$rank == rank)
}))
}
getTreeListNumber(myList, 1, 2)
#[1] 2https://stackoverflow.com/questions/69747317
复制相似问题