我查看了V和E的来源,我不确定它们是如何工作的。 这是V的代码:
> V
function (graph)
{
if (!is.igraph(graph)) {
stop("Not a graph object")
}
vc <- vcount(graph)
if (vc == 0) {
res <- numeric()
}
else {
res <- 0:(vc - 1)
}
class(res) <- "igraph.vs"
ne <- new.env()
assign("graph", graph, envir = ne)
attr(res, "env") <- ne
res
}
我不确定在这里调用assign和attr的目的是什么。 分配图表是否会创建图表的新副本?效率/效率如何?也就是说,这产生的图表副本数量如下所示:
V(g)$someattr <- somevector
感谢您的帮助。
答案 0 :(得分:1)
使用V
生成顶点序列时,对assign
和attr
的调用会存储用于创建序列的图形副本以及顶点序列对象本身。这样,当您执行V(g)$color = 'blue'
之类的操作时,可以在此g
副本的上下文中方便地评估顶点序列。如果您检查igraph.vs
类可用的其中一种方法,这一点很清楚。
> methods(class='igraph.vs')
[1] [.igraph.vs [<-.igraph.vs $.igraph.vs $<-.igraph.vs print.igraph.vs
> `$.igraph.vs`
function (x, name)
{
get.vertex.attribute(get("graph", attr(x, "env")), name,
x)
}
<environment: namespace:igraph>
很明显,$
索引操作将在用于创建顶点序列的图形环境的上下文中进行评估。
你提出了一个很好的观点,虽然这个 创建了图的多个副本(可能会收集垃圾,但仍然很好知道)。如果在创建顶点序列g
之后修改图vs = V(g)
的属性,则可以轻松演示这一点。该属性在g
中更新,但未在g
附加的环境中存储的vs
副本中更新。
> g = graph(c(0:1), directed=F)
> g = set.vertex.attribute(g, 'color', value='blue')
> vs = V(g)
> vs$color
[1] "blue" "blue"
> g = set.vertex.attribute(g, 'color', value='red')
> V(g)$color
[1] "red" "red"
> vs$color
[1] "blue" "blue"