开发者

How do the iterators V and E in igraph using R work?

I've looked through the source for V and E and I'm not really sure how they work. Here's the code for V:

> V
function (graph)
{
    if (!is.ig开发者_StackOverflow社区raph(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
}

I'm not really sure what purpose the calls to assign and attr serve here. Does assigning graph create a new copy of graph? How efficient/inefficient is this? That is, how many copies of graph does this generate say in code like:

V(g)$someattr <- somevector

Thanks for the help.


When generating a vertex sequence with V, the calls to assign and attr store a copy of the graph that was used to create the sequence along with the vertex sequence object, itself. This way when you do something like V(g)$color = 'blue', the vertex sequence can be conveniently evaluated in the context of this copy of g. This is clear if you inspect one of the methods available for the igraph.vs class.

> 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>

Here it is clear that the $ indexing operation will get evaluated in the context of the graph environment that was used to create the vertex sequence.

You bring up a good point though that this does create multiple copies of the graph (which presumably get garbage collected, but it's still good to be aware of). This is easily demonstrated if you modify attributes of a graph g, after you have already created a vertex sequence vs = V(g). The attribute is updated in g, but not in the copy of g that is stored in the environment attached to 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"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜