dan dan - 20 days ago 5
R Question

Covert a graphNEL object to network object through an igraph object

I'm trying to convert a

graphNEL
DAG
into a
network
object in
R
.

Here's my
graphNEL
object, taken from the
topGO
package
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)


And

> class(attr(topgo.obj,"graph"))
[1] "graphNEL"
attr(,"package")
[1] "graph"


So:

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


Now, I cannot convert a
graphNEL
object directly to a
network
object, but I think it should be possible through an
igraph
object.

So:

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


And then:

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


But that throws is error:

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


With
intergraph
's example this works fine of course:

intergraph.network <- asNetwork(exIgraph,amap=attrmap())


Examining
exIgraph
and
topgo.igraph
:

> 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 GO:0000075->GO:0022402
[7] GO:0000077->GO:0031570 GO:0000077->GO:0006974 GO:0000079->GO:1904029 GO:0000079->GO:0071900 GO:0000082->GO:0044772 GO:0000082->GO:0044843
[13] GO:0000086->GO:0000278 GO:0000086->GO:0044772 GO:0000086->GO:0044839 GO:0000122->GO:0006357 GO:0000122->GO:0045892 GO:0000122->GO:0006366
[19] GO:0000165->GO:0035556 GO:0000165->GO:0023014 GO:0000187->GO:0032147 GO:0000187->GO:0043406 GO:0000209->GO:0016567 GO:0000226->GO:1902589
[25] GO:0000226->GO:0007010 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 GO:0000819->GO:0051276
[37] GO:0000902->GO:0032989 GO:0000910->GO:0022402 GO:0000910->GO:0051301 GO:0001501->GO:0048731 GO:0001516->GO:0046457 GO:0001516->GO:0006693
[43] GO:0001525->GO:0048514 GO:0001525->GO:0048646 GO:0001525->GO:0044767 GO:0001558->GO:0016049 GO:0001558->GO:0051128 GO:0001558->GO:0040008
+ ... omitted several edges


They seem to be comparable as far as this test goes so I don't understand what the source of the error is.

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"