首页 > 解决方案 > 获取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 的评论:返回 R 中每对节点之间的相互节点列表

或者

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

我认为原因是数据结构不同。但我不知道如何解决它。

感谢您的帮助。

标签: rnetworkingigraph

解决方案


之后您可以将数字 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

推荐阅读