Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 955
starflyer Avatar asked Nov 13 '22 18:11

starflyer


1 Answers

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"
like image 172
John Colby Avatar answered Nov 16 '22 18:11

John Colby