igraph双向网络投影忽略方向

时间:2018-11-27 11:06:35

标签: r graph igraph bipartite

示例:

require(igraph)
require(tidygraph)
require(ggraph)
require(data.table)

nodes <- data.table(id = 1:6, 
                    label = c("a1", "b1", "a2", "a3", "b2", "a4"), 
                    type = c("A", "B", "A", "A", "B", "A"))

edges <- data.table(from = c(1, 2, 2, 3, 5),
                    to = c(2, 3, 4, 5, 6))

network <- graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)

ggraph(network) + 
  geom_edge_link(arrow = arrow(length = unit(4, 'mm')), 
                 start_cap = circle(3, 'mm'), 
                 end_cap = circle(3, 'mm')) + 
  geom_node_point(aes(color = type), size = 7) +
  geom_node_text(aes(label = label)) +
  theme_graph()

这就是我们得到的:

enter image description here

然后我们创建投影:

V(network)$type <- bipartite_mapping(network)$type
network_projections <- bipartite_projection(network)

ggraph(network_projections$proj1) + 
  geom_edge_link(arrow = arrow(length = unit(4, 'mm')), 
                 start_cap = circle(3, 'mm'), 
                 end_cap = circle(3, 'mm')) + 
  geom_node_point(size = 7, color = 2, alpha = .6) +
  geom_node_text(aes(label = label)) +
  theme_graph()

这就是我们得到的:

enter image description here

投影显示链接a2-> a3,该链接应该存在。这显然意味着没有考虑方向性。

据我所知-igraph库计算出的基础发生率矩阵的计算方式不考虑方向性。有没有我想念的功能或其他R库可以进行双向网络定向投影?

1 个答案:

答案 0 :(得分:0)

这绝不是最佳解决方案,更像是解决方法:

(从原始问题的代码继续)

# get a list of adjacent vertices from perspective of projections to validate directional connection
adj_vert <- adjacent_vertices(network_projections$proj1, v = nodes[type == "A", .I])

# container
projection_edges <- data.table(from = character(),
                               to = character())

for(i in names(adj_vert)){

  # find simplest path, from iterated vertice to vector of shortlisted names
  orig_paths <- all_simple_paths(network, from = as.numeric(i), to = as.numeric(names(adj_vert[[i]])), mode = "out")

  if(length(orig_paths) > 0){
    for(j in 1:length(orig_paths)){

      # for each path, take first and last element to skip "B" nodes in between
      projection_edges <- rbind(projection_edges,
                                data.table(from = names(orig_paths[[j]])[1],
                                           to = rev(names(orig_paths[[j]]))[1]))
    }
  }
}

# corrected projection

network_projection_corrected <- graph_from_data_frame(d = projection_edges, vertices = nodes[type == "A"], directed = TRUE)

ggraph(network_projection_corrected) + 
  geom_edge_link(arrow = arrow(length = unit(4, 'mm')), 
                 start_cap = circle(3, 'mm'), 
                 end_cap = circle(3, 'mm')) + 
  geom_node_point(aes(color = type), size = 7) +
  geom_node_text(aes(label = label)) +
  theme_graph()

我们得到了:

enter image description here

这看起来并不可怕,即使它是一个嵌套循环。因为对于每个循环,所有相邻的“ A”型顶点都是已知的,所以我们只是有效地检查方向连接。但是,我认为这应该是内置功能。<​​/ p>

此外,我不知道我提出的方法可能给“现实”网络带来的错误。因此,它绝不是牢固的。