获取R中每对直接连接的节点之间相互连接的节点列表

Get obtain a list of mutually connected nodes between every pair of directly connected nodes in R

我想获得图中每对直接连接的节点之间相互连接的节点列表:

我的数据如下所示:

countryA <- c("USA", "USA", "USA", "USA", "GERMANY", "GERMANY", "GERMANY", "JAPAN", "JAPAN", "CHINA", "USA", "USA", "FRANCE")

countryB <- c("MEXICO", "CANADA", "GERMANY", "JAPAN", "CANADA", "JAPAN", "FRANCE", "KOREA", "CHINA", "KOREA", "KOREA",  "CHINA", "CANADA")

year <- (c(2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000))
data <- data.frame(countryA, countryB, year)
data$countryA <- as.character(data$countryA)
data$countryB <- as.character(data$countryB)

edge <- graph_from_data_frame(data, directed = FALSE)

plot(edge)

例如,在此图中,美国和日本共享共同节点中国、韩国和德国。

我想构建如下数据框:

任一 (1)

node1    node2      mutual
USA      Japan      Korea, China
Japan    USA        Korea, China
USA      Germany    Canada
Germany  USA.       Canada
Korea    Japan      USA, China
Japan    Korea      USA, China
Korea    China      Japan
China    Korea      Japan    
China    Japan      Korea, USA
Japan    China      Korea, USA
France   Germany    Canada
Germany  France    Canada
France   Canada    Germany
Canada   France    Germany

或 (2)

node1    node2      mutual
USA      Japan      Korea
USA      Japan      China
Japan    USA        Korea
Japan    USA        China
USA      Germany    Canada
Germany  USA        Canada
Korea    Japan      USA
Korea    Japan      China
Japan    Korea      USA
Japan    Korea      China
Korea    China      Japan
China    Korea      Japan
China    Japan      Korea
Japan    China      Korea
Japan    China      USA
China    Japan      USA
France   Germany    Canada
Germany  France     Canada
France   Canada    Germany
Canada   France    Germany

我试过下面的代码

do.call(
  rbind,
  apply(
    matrix(triangles(G), nrow = 3),
    2,
    function(v) {
      u <- t(sapply(seq_along(v), function(k) t(v[-k])))
      setNames(data.frame(cbind(v, rbind(u, u[, 2:1]))), c("node1", "node2", "mutual"))
    }
  )
)

此代码归功于@ThomasIsCoding 在 link 中的评论:

get_mutuals <- function(g) {
  do.call("rbind", lapply(seq.int(1, vcount(g)-1), function(i) {
    do.call("rbind", lapply(seq.int(i+1, vcount(g)), function(j) {
      ni <- neighbors(g, i)
      nj <- neighbors(g, j)
      overlap <- intersect(ni, nj)
      if (length(overlap) & i %in% nj) {
        data.frame(i=i, j=j, m=overlap)
      } else {
        NULL
      }
    }))
  }))
}
get_mutuals(G)

此代码归功于@MrFlick。

这些代码在我使用时工作正常 下面的数据,但是当我尝试使用上面的数据时,它给出了数字作为节点 ID 而不是国家/地区名称。

library(igraph)
G <- graph(c(1,2,1,3,1,4,2,4, 2,3,2,5,3,5,4,5,5,6,5,7,7,8,7,9), directed=F)
 
plot(G)

 node1   node2     mutual
   1      2          3
   1      2          4
   1      3          2
   1      4          2
   2      3          1
   2      3          5

我认为原因是数据结构不同。但我不确定如何修复它。

感谢您的帮助。

您可以将数字 ID 与之后的名称重新关联:

df <- get_mutuals(edge)

names <- as_ids(V(edge))

for (i in seq_along(df)) {
  df[,i] <- names[df[,i]]
}
> head(df, 5)
    i       j       m
1 USA GERMANY   JAPAN
2 USA GERMANY  CANADA
3 USA   JAPAN GERMANY
4 USA   JAPAN   CHINA
5 USA   JAPAN   KOREA

试试这个

do.call(
  rbind,
  apply(
    matrix(names(triangles(edge)), nrow = 3),
    2,
    function(v) {
      u <- t(sapply(seq_along(v), function(k) t(v[-k])))
      setNames(data.frame(cbind(v, rbind(u, u[, 2:1]))), c("node1", "node2", "mutual"))
    }
  )
)

这给出了

     node1   node2  mutual
1      USA GERMANY  CANADA
2  GERMANY     USA  CANADA
3   CANADA     USA GERMANY
4      USA  CANADA GERMANY
5  GERMANY  CANADA     USA
6   CANADA GERMANY     USA
7      USA GERMANY   JAPAN
8  GERMANY     USA   JAPAN
9    JAPAN     USA GERMANY
10     USA   JAPAN GERMANY
11 GERMANY   JAPAN     USA
12   JAPAN GERMANY     USA
13     USA   JAPAN   KOREA
14   JAPAN     USA   KOREA
15   KOREA     USA   JAPAN
16     USA   KOREA   JAPAN
17   JAPAN   KOREA     USA
18   KOREA   JAPAN     USA
19     USA   JAPAN   CHINA
20   JAPAN     USA   CHINA
21   CHINA     USA   JAPAN
22     USA   CHINA   JAPAN
23   JAPAN   CHINA     USA
24   CHINA   JAPAN     USA
25     USA   CHINA   KOREA
26   CHINA     USA   KOREA
27   KOREA     USA   CHINA
28     USA   KOREA   CHINA
29   CHINA   KOREA     USA
30   KOREA   CHINA     USA
31 GERMANY  CANADA  FRANCE
32  CANADA GERMANY  FRANCE
33  FRANCE GERMANY  CANADA
34 GERMANY  FRANCE  CANADA
35  CANADA  FRANCE GERMANY
36  FRANCE  CANADA GERMANY
37   JAPAN   CHINA   KOREA
38   CHINA   JAPAN   KOREA
39   KOREA   JAPAN   CHINA
40   JAPAN   KOREA   CHINA
41   CHINA   KOREA   JAPAN
42   KOREA   CHINA   JAPAN