请考虑以下带有两个类别(“数字”和“字符”)顶点的图表:
library(igraph)
id <- c("1","2","A","B")
category <- c("digit","digit","char","char")
from <- c("1","1","2","A","A","B")
to <- c("2","A","A","B","1","2")
nodes <- cbind(id,category)
edges <- cbind(from,to)
g <- graph.data.frame(edges, directed=TRUE, vertices=nodes)
现在我想根据属性“category”收缩顶点:
category_attr <- get.vertex.attribute(g, "category")
map = setNames(c(1:2), c("digit","char"))
category_attr <- map[unlist(category_attr)]
igraph_category <- contract.vertices(g, category_attr)
print(get.data.frame(igraph_category, what="vertices"))
# name
# c("1", "2") 1, 2
# c("A", "B") A, B
然而,我希望新图形的“id”和属性“name”成为缩小顶点的“类别”,并且还显示一个列,其中显示了缩小的顶点数。
总而言之,我想:
print(get.data.frame(igraph_category, what="vertices"))
# name frequency
# digit digit 2
# char char 2
答案 0 :(得分:0)
首先,使用因子进行收缩实际上更容易。
对于您的问题,关键是在合并顶点时指定igraph应该对顶点属性执行的操作。如果您不希望保留原始名称,则可以删除它们,并指定应保留category
属性。 first
表示合并多个顶点时igraph只取第一个顶点的category
属性。由于所有顶点合并为一个具有相同的category
,因此这很好。
然后您可以在新图表中使用类别作为名称。
g2 <- contract.vertices(g, factor(V(g)$category),
vertex.attr.comb=list(category="first",
name="ignore"))
V(g2)$name <- V(g2)$category
在这种情况下, g2
将是一个多图形(或另一个术语中的非简单图形),它将包含类别之间的多个边缘,如果属于该属性的原始顶点之间存在多个边缘类别。您可以折叠多个边并获得频率
作为边缘属性。
最简单的方法是使用边缘属性weight
,因为这是默认情况下的总和
结合边缘:
E(g2)$weight <- 1
g3 <- simplify(g2, remove.loops=FALSE)
str(g3, e=T)
# IGRAPH DNW- 2 4 --
# + attr: category (v/c), name (v/c), weight (e/n)
# + edges (vertex names) and their attributes:
# edge weight
# [1] char ->char 1
# [2] char ->digit 2
# [3] digit->char 2
# [4] digit->digit 1