在R Igraph中提取开放三角形(网络分析)

时间:2016-05-22 02:53:39

标签: r igraph

我有一个边缘列表,我想要提取打开三角形,这意味着如果:A知道B和B知道C,但是C的关系没有在图中捕获。

有没有办法提取这个在R?我知道你可以用普通的三角形来做,但我想知道你是否可以提取空心三角形。

我在R中创建了一个网络图,边缘列表如下所示:

structure(list(ego = c(323L, 174L, 174L, 174L, 174L, 174L, 174L, 
174L, 174L, 174L, 428L, 428L, 428L, 428L, 428L, 428L, 428L, 428L, 
364L, 364L, 364L, 364L, 364L, 364L, 364L, 364L, 422L, 422L, 422L, 
422L, 422L, 422L, 422L, 422L, 329L, 329L, 329L, 329L, 329L, 329L, 
329L, 329L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 330L, 330L, 
330L, 330L, 330L, 330L, 330L, 330L, 415L, 428L), alter = c(174L, 
323L, 428L, 364L, 422L, 329L, 31L, 330L, 415L, 392L, 174L, 364L, 
422L, 329L, 31L, 330L, 415L, 392L, 174L, 428L, 422L, 329L, 31L, 
330L, 415L, 392L, 174L, 428L, 364L, 329L, 31L, 330L, 415L, 392L, 
174L, 428L, 364L, 422L, 31L, 330L, 415L, 392L, 174L, 428L, 364L, 
422L, 329L, 330L, 415L, 392L, 174L, 428L, 364L, 422L, 329L, 31L, 
415L, 392L, 174L, 323L), advice_tie = c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L)), .Names = c("ego", "alter", "advice_tie"
), class = "data.frame", row.names = c(NA, -60L))

我在R:

中创建了如下网络图
edges2 <- graph.data.frame(edges)

edges3 <- as.undirected(edges2, mode='collapse')
summary(edges3)

plot(edges3)
edges

这是edge3在变为无向之后的样子:

IGRAPH UN-- 10 37 -- 
+ attr: name (v/c)
+ edges (vertex names):
 [1] 323--174 323--428 174--428 174--364 428--364
 [6] 174--422 428--422 364--422 174--329 428--329
 [11] 364--329 422--329 174--31  428--31  364--31 
 [16] 422--31  329--31  174--330 428--330 364--330
 [21] 422--330 329--330 31 --330 174--415 428--415
 [26] 364--415 422--415 329--415 31 --415 330--415
 [31] 174--392 428--392 364--392 422--392 329--392
 [36] 31 --392 330--392

期望输出(因为在这种情况下,323和392是唯一不连接除428以外的所有其他内容的输出):

415  174 323
31   174 323
422  174 323
329  174 323
364  174 323
392  174 323
330  174 323
31   415 392
422  415 392
329  415 392
364  415 392
392  415 392
330  415 392
428  415 392
174  415 392 

enter image description here

我希望这是有道理的!感谢

1 个答案:

答案 0 :(得分:2)

如果我们从给定的边缘开始,首先我们构造一个igraph对象,我们将其称为G而不是edges3,因为它是图形不是边缘

library(igraph)
g <- graph.data.frame(edges)
G <- as.undirected(g, mode='collapse')

为了找到所有空心三角形,我们遍历图形的所有顶点,这是lapply(as_ids(V(G)), ..在第一行中所做的事情,并找出所有邻居并再次循环,即lapply(as_ids(neighbors(G, v)), ..

我们在第四行进行条件检查,以确保原始v和邻居的邻居之间的距离为2,从而保证三角形是开放的(未连接,也不是v本身)。

结果将作为有序向量返回,这有助于我们稍后删除重复的空心三角形,这是由第一行开头的unique函数完成的。

openTriList <- unique(do.call(c, lapply(as_ids(V(G)), function(v) {
    do.call(c, lapply(as_ids(neighbors(G, v)), function(v1) {
        v2 <- as_ids(neighbors(G, v1))
        v2 <- v2[shortest.paths(G, v, v2) == 2]

        if(length(v2) != 0) {
            lapply(v2, function(vv2) { c(v, v1, vv2)[order(c(v, v1, vv2))] })
        } else { list() }
    }))
})))

这段代码将返回一个空心三角形列表,您可以通过do.call(rbind, openTriList)将其转换为矩阵,其中每行代表一个唯一的开放三角形:

> do.call(rbind, openTriList)
      [,1]  [,2]  [,3] 
 [1,] "174" "323" "364"
 [2,] "174" "323" "422"
 [3,] "174" "323" "329"
 [4,] "174" "31"  "323"
 [5,] "174" "323" "330"
 [6,] "174" "323" "415"
 [7,] "174" "323" "392"
 [8,] "323" "364" "428"
 [9,] "323" "422" "428"
[10,] "323" "329" "428"
[11,] "31"  "323" "428"
[12,] "323" "330" "428"
[13,] "323" "415" "428"
[14,] "323" "392" "428"
[15,] "174" "392" "415"
[16,] "392" "415" "428"
[17,] "364" "392" "415"
[18,] "392" "415" "422"
[19,] "329" "392" "415"
[20,] "31"  "392" "415"
[21,] "330" "392" "415"