dan dan - 22 days ago 6
R Question

Convert a graphNEL graph to a network graph

I'm trying to convert a

graphNEL
graph to
network
graph.

Here's my example using
topGO
's
vignette
:

library(topGO)
library(ALL)
data(ALL)
data(geneList)
affyLib <- paste(annotation(ALL),"db",sep= ".")
library(package=affyLib,character.only=TRUE)
topgo.obj <- new("topGOdata",description="Simple session",ontology="BP",allGenes=geneList,geneSel=topDiffGenes,nodeSize=10,annot=annFUN.db,affyLib=affyLib)

topgo.graph <- attr(topgo.obj,"graph")


And trying to convert
topgo.graph
to a network through
intergraph


library(network)
library(sna)
library(scales)
library(igraph)
library(intergraph)

topgo.igraph <- graph_from_graphnel(topgo.graph,name=TRUE,weight=TRUE,unlist.attrs=TRUE)


And finally

topgo.network <- asNetwork(topgo.igraph,amap=attrmap())


throws this error:

Error in as.data.frame.default(x[[i]], optional = TRUE) :
cannot coerce class ""environment"" to a data.frame


When I try this with
intergraph
's example:

asNetwork(exIgraph)


it works fine
and as far I can tell
exIgraph
and topgo.igraph look similar:

> exIgraph
IGRAPH D--- 15 11 --
+ attr: label (v/c), label (e/c)
+ edges:
[1] 2-> 1 3-> 1 4-> 1 5-> 1 6-> 7 8-> 9 10->11 11->12 12->13 13->14 14->12

> topgo.igraph
IGRAPH DNW- 1017 2275 --
+ attr: name (v/c), genes (v/x), weight (e/n)
+ edges (vertex names):
[1] GO:0000003->GO:0008150 GO:0000070->GO:0000278 GO:0000070->GO:0007067 GO:0000070->GO:1903047 GO:0000070->GO:0000819
[6] GO:0000075->GO:0022402 GO:0000077->GO:0031570 GO:0000077->GO:0006974 GO:0000079->GO:1904029 GO:0000079->GO:0071900
[11] GO:0000082->GO:0044772 GO:0000082->GO:0044843 GO:0000086->GO:0000278 GO:0000086->GO:0044772 GO:0000086->GO:0044839
[16] GO:0000122->GO:0006357 GO:0000122->GO:0045892 GO:0000122->GO:0006366 GO:0000165->GO:0035556 GO:0000165->GO:0023014
[21] GO:0000187->GO:0032147 GO:0000187->GO:0043406 GO:0000209->GO:0016567 GO:0000226->GO:1902589 GO:0000226->GO:0007010
[26] GO:0000226->GO:0007017 GO:0000278->GO:0007049 GO:0000280->GO:0048285 GO:0000302->GO:0006979 GO:0000302->GO:1901700
[31] GO:0000723->GO:0006259 GO:0000723->GO:0032200 GO:0000723->GO:0060249 GO:0000819->GO:1902589 GO:0000819->GO:0098813
[36] GO:0000819->GO:0051276 GO:0000902->GO:0032989 GO:0000910->GO:0022402 GO:0000910->GO:0051301 GO:0001501->GO:0048731
+ ... omitted several edges


Any idea?

Answer

This is happening because of the "gene" attribute. If you view it using V(topgo.igraph)$gene, you will see it return a list of environments rather than a vector. When deep in the intergraph code, it tries to coerce the vertex attributes into a data frame, which it cannot do. (This happens in the dumpAttr() function -- see getAnywhere(dumpAttr.igraph).)

To solve this, you can simple delete the attribute:

topgo.igraph <- delete_vertex_attr(topgo.igraph,"genes")
topgo.network <- asNetwork(topgo.igraph,amap=attrmap())

The argument unlist.attrs=T I think is designed to prevent the exact problem above, but it is not working in this case. This might be due to the naming convention used by the genes in the network.

If you look at the attributes from the original graphNEL object, you will notice that it consists of objects of class environment:

> head(graph::nodeData(topgo.graph, attr = "genes"))
$`GO:0000003`
<environment: 0x15c005ae0>

$`GO:0000070`
<environment: 0x15c136bf0>

$`GO:0000075`
<environment: 0x15c118a70>

$`GO:0000077`
<environment: 0x15c13ae70>

$`GO:0000079`
<environment: 0x163145670>

$`GO:0000082`
<environment: 0x16313d148>)

You could also alter the attribute data in the original topGO object to solve the problem as well:

nodeData(topgo.graph, attr = "genes") <- topgo.obj@graph@nodes
topgo.igraph <- graph_from_graphnel(topgo.graph,name=TRUE,weight=TRUE,unlist.attrs=TRUE)
topgo.network <- asNetwork(topgo.igraph,amap=attrmap())

This preserves the genes a vertex attributes, if you want that:

> head(network::get.vertex.attribute(topgo.network, "genes"))
[1] "GO:0000003" "GO:0000070" "GO:0000075" "GO:0000077" "GO:0000079" "GO:0000082"