我有一个从几个树状结构的图像中提取的图表。该图具有每个关节点的顶点,即使该点不是分支或结束(即节点顺序为2)。我想删除这些order-2顶点,但保持连通性,以便通过这些中间体连接的分支点或末端顶点现在通过单个边连接。我可以通过一次一个地删除顶点和连接边来为小图做到这一点,但是当处理10,000多个边时这很慢。
这是一个示例起始图。我想删除(例如)顶点8和6,同时插入连接9和4的边。同样,我想在插入7和4之间的边时删除顶点5。
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")
答案 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)
答案 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)