5

我查看了 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

谢谢您的帮助。

4

1 回答 1

1

使用 生成顶点序列时V,调用assignattr存储用于创建序列的图的副本以及顶点序列对象本身。这样,当你做类似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"
于 2011-11-13T22:35:53.580 回答