R语言 对于非常大的数据,标识某个节点的所有子节点

yrdbyhpb  于 2023-05-26  发布在  其他
关注(0)|答案(1)|浏览(126)

我试图找到一个大型图对象(约100万条边)中的所有下游节点。
下面的代码是使用igraphthis answer改编而来的,但是在我结束它之前它运行了20多分钟。我看到了hR包(参见here),但它也有数据大小的问题。
我对图形分析是新手,不确定是否有更好的方法

library(tidyverse)
library(igraph)

graph_df <- # real example has 1.2M connections
  make_tree(100000, children = 3)

leafnodes <- # bottleneck
  sapply(
    X = V(graph_df), 
    FUN = \(x) length(neighbors(graph_df, x)) == 0
  )

find_all_children <- function(root) {
  paths <- 
    get.all.shortest.paths(
      graph = graph_df, 
      from = V(graph_df)[root], 
      to = leafnodes
    )$res
  
  tibble(
    path = map_chr(paths, ~paste(.x, collapse = " -> "))
  )
}

# desired output
find_all_children(12)
#> 12 -> 35 -> 104 -> 311 -> 932 -> 2795 -> 8384
#> 12 -> 35 -> 104 -> 311 -> 932 -> 2795 -> 8385
#> 12 -> 35 -> 104 -> 311 -> 932 -> 2795 -> 8386

find_all_children(1234)
#> 1234 -> 3701 -> 11102 -> 33305 -> 99914
#> 1234 -> 3701 -> 11102 -> 33305 -> 99915
#> 1234 -> 3701 -> 11102 -> 33305 -> 99916

附加问题:
是否有一个purrr方法来替换这里的sapply()?我对map()没有任何运气

m1m5dgzv

m1m5dgzv1#

也许你可以先尝试subgraph + subcomponent来修剪你的树,然后找到all_simple_paths,例如,

n <- 100000

g <- make_tree(n, children = 3) %>%
    set_vertex_attr(name = "name", value = seq(vcount(.)))

find_all_children <- function(g, root) {
    g %>%
        subgraph(subcomponent(root, "out")) %>%
        all_simple_paths(1, V(.)[degree(., mode = "out") == 0])
}

并运行以下代码行

r12 <- find_all_children(g, 12)
r1234 <- find_all_children(g, 1234)

这甚至可以用n <- 100000在几秒钟内完成。

相关问题