在 R 上的 igraph 中查找大型数据集中的根顶点

Finding root vertices in largeish dataset in igraph on R

假设您有一个根据边列表制作的图,并且有几百个顶点。我要做的是识别初始顶点集,所有后续顶点都与之相关(如母亲或家谱)。

这是一个数据集,表示 'ice islands',从冰川中分离出来并漂浮在海面上的大片状冰层。最初的裂缝代表根节点。随后的顶点是对这些碎片的重新观察,这些碎片要么更小(融化的岛),要么已经断开(因此源顶点具有两条边的网络并继续形成两个新顶点)。

有没有一段代码或一个函数可以为我轻松做到这一点?如果我在情节中添加标签,就无法阅读。我能够找到的大多数操纵根节点的方法都涉及小样本数据集,您可以在其中任意命名图中的事物,或使用顶点的实际名称。我的数据来自一个巨大的已建立的具有超长数字字符名称的 CSV。这使它变得困难。

我也是编码新手,R 对我来说是一场噩梦。请温和并使用简单的例子!如果您认为有帮助,我可以附上我的代码,我的所有数据都是从服务器中提取的,我不知道从您的角度来看是否会很清楚。

谢谢。

对于任何节点 n,您可以使用 找到 节点的边数 neighbors(g, n, mode="in")。如果一个节点没有任何边进入它,它就是一个初始顶点。因此,您可以只测试所有节点有多少条边进入节点,select 那些答案为零的边。

这是一个简单的示例图:

library(igraph)
set.seed(2017)
g = erdos.renyi.game(12, 20, type="gnm", directed=TRUE)
plot(g)

现在我们可以找到根节点了。

which(sapply(sapply(V(g), 
    function(x) neighbors(g,x, mode="in")), length) == 0)
[1] 1 2

这表示节点 1 和 2 是源。

既然你说你是初学者,那我就稍微解释一下吧。

function(x) neighbors(g,x, mode="in") 是一个函数,它将节点作为参数并使用 neighbors 到 return 节点列表 y 具有从 y 到 x 的 link (x 的 parents)。

sapply(V(g), function(x) neighbors(g,x, mode="in")) 将该函数应用于图中的所有节点,因此给出每个节点的 parents 列表。我们对没有 parents 的节点感兴趣,因此我们想要此列表的长度为零的节点。因此,我们将长度应用于 parents 的列表并检查哪些长度为零。

enter code here如果图形包含自环,G5W 的解决方案将失败。另一种方法:

library(igraph)
set.seed(2017)
g = erdos.renyi.game(12, 20, type="gnm", directed=TRUE)
rts <- V(g)[degree(g, mode=c("in"), loops = F) == 0]        # find roots, that is, in-degree is zero
paste(c("Roots: ", rts), collapse=" ")
plot(g, layout=layout_with_sugiyama(g)$layout)              # plot graph in layers

g2 <- simplify(g, remove.loops = T, remove.multiple = T)    # reduce to simple graph without loops
stopifnot(max(clusters(g2, mode=c("strong"))$csize) == 1)   # stop when cycles

E(g2)$weight <- -1                                          # shortest path is longest negative
dis <- (-distances(g2, mode="in") )                         # matrix VxV of depth of layers, depth from top to bottom
lay = as.matrix(apply(dis, 1, max))                         # maximum of distances in successors
as.matrix(apply(-distances(g2, mode="out"), 1, max))        # or reverse from bottom to top

plot(g, layout=layout_with_sugiyama(g, layer=lay)$layout)