在R中的igraph:如何在保持连通性的同时删除非分支点顶点?

时间:2017-06-28 17:26:08

标签: r igraph

我有一个从几个树状结构的图像中提取的图表。该图具有每个关节点的顶点,即使该点不是分支或结束(即节点顺序为2)。我想删除这些order-2顶点,但保持连通性,以便通过这些中间体连接的分支点或末端顶点现在通过单个边连接。我可以通过一次一个地删除顶点和连接边来为小图做到这一点,但是当处理10,000多个边时这很慢。

这是一个示例起始图。我想删除(例如)顶点8和6,同时插入连接9和4的边。同样,我想在插入7和4之间的边时删除顶点5。

enter image description here

edge_matrix = cbind(
  c(1,2,3,4,4,5,6,8,9,9,10,11),
  c(2,3,4,5,6,7,8,9,10,11,12,13))
example_graph = graph.data.frame(edge_matrix, directed=F)

structure(list(13, FALSE, c(1, 2, 3, 4, 5, 10, 6, 7, 8, 9, 11, 
12), c(0, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9), c(0, 1, 2, 3, 4, 
6, 7, 8, 9, 5, 10, 11), c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
), c(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), c(0, 1, 2, 
3, 5, 6, 7, 8, 10, 11, 12, 12, 12, 12), list(c(1, 0, 1), structure(list(), .Names = character(0)), 
    structure(list(name = c("1", "2", "3", "4", "5", "6", "8", 
    "9", "10", "11", "7", "12", "13")), .Names = "name"), list()), 
    <environment>), class = "igraph")

2 个答案:

答案 0 :(得分:3)

实际上,最好只删除图形中的2级节点,而不是尝试用最少的信息重建图形。这个函数不会对递归感到烦恼,而且效率可能更高

trim_deg2 <- function(g) {
  get_deg2 <- function(x) {
    dd <- degree(x)
    trim <- V(x)[names(dd[dd==2])]    
  }
  ng <- g
  trim <- get_deg2(ng)
  while(length(trim)) {
    tv <- trim[1]
    touch <- adjacent_vertices(ng, tv)[[1]]
    ng <- delete_edges(ng, E(ng)[tv %--% touch])
    ng <- add_edges(ng, touch$name)
    ng <- delete_vertices(ng, V(ng)[tv])
    trim <- get_deg2(ng)
  }
  ng
}

它适用于您的示例数据

g <- trim_deg2(example_graph)
plot(g)

enter image description here

答案 1 :(得分:0)

我很确定我这样做的方式是错误的,但是这里有一个函数,它基本上会在图中寻找具有度数的节点!= 2并将它们全部重新连接到一个新的图形中。

walk_thin <- function(g, v=V(g)[[1]]) {
  dd <- degree(g)
  keep <- V(g)[names(dd[dd!=2])]
  edges <- c()
  find_next <- function(v, from, past = c()) {
    v2 <- adjacent_vertices(g, v)[[1]]
    v2 <- v2[!v2 %in% past]
    for(i in seq_along(v2)) {
      nv <- v2[i]
      if (nv %in% keep) {
        edges <<- c(c(from, nv)$name, edges)
        find_next(nv, nv, past=c(nv, past))
      } else {
        find_next(nv, from, past=c(nv, past))
      }
    }
  }
  find_next(v, v, v)  
  make_graph(edges,directed = FALSE)
}

它似乎适用于您的示例数据

g <- walk_thin(example_graph)
plot(g) 

enter image description here