Nothing
createPathwayGraphs <- function(org, pathways, edgeTypes, doubleEdges, choice,
groupMode)
{
if ( missing(edgeTypes) )
{
edgeTypes <- getEdgeTypes()
}
if ( missing(doubleEdges) )
{
doubleEdges <- getDoubleEdges()
}
if ( missing(choice) )
{
choice <- 'reactions'
}
if ( missing(groupMode) )
{
groupMode <- 'expand'
}
if (missing(org))
{
message('Please specify a valid organism id.')
return(NULL)
}
# Xml directory for organism
xmlDir <- paste(cache$dirs$xml, org, sep='//')
# Choose valid pathways
if (missing(pathways))
{
paths <- list.files(xmlDir)
}
if (!missing(pathways))
{
paths <- paste(org, pathways, '.xml', sep='')
}
message('Creating adjacency matrices...', appendLF = FALSE)
# Create compact adjacency matrices for given pathways.
types <- getPathwayType(paste(xmlDir, paths, sep='//'))
N <- length(paths)
cores <- ifelse( N > detectCores()*10, 'default', 1 )
export <- c(
'nonMetabolicPathwayToGraph', 'expandMetabolicGraph',
'removeCompoundsNonMetabolicGraph',
'metabolicPathwayToGraph', 'expandNonMetabolicGraph',
'removeCompoundsMetabolicGraph',
'xmlTreeParse', 'xmlRoot', 'xmlGetAttr', 'xmlName', 'xmlChildren')
cAdjMats <- .doSafeParallel(
funcName=pathwayToGraph,
export=export,
combine='default',
N=length(paths),
cores=cores,
xmlDir, paths, types, FALSE, edgeTypes,
doubleEdges, choice, groupMode)
names(cAdjMats) <- gsub('.xml', '', paths)
# Create expanded adjacency matrices with edge type information
eAdjMats <- .doSafeParallel(funcName=pathwayToGraph,
export=export,
combine='default',
N=length(paths),
cores=cores,
xmlDir, paths, types, TRUE, edgeTypes,
doubleEdges, choice, groupMode)
names(eAdjMats) <- gsub('.xml', '', paths)
message('done.')
return(list(combined=cAdjMats, expanded=eAdjMats, org=org))
}
pathwayToGraph <- function (i, ...)
{
# ------- Unpacking arguments -------
args <- list(...)
dir <- args[[1]]
file <- args[[2]][i]
type <- args[[3]][i]
expand <- args[[4]]
edgeTypes <- args[[5]]
doubleEdges <- args[[6]]
choice <- args[[7]]
groupMode <- args[[8]]
# ----------------------------------
adjMat <- NULL
if ( type == 'Metabolic' && choice == 'reactions' )
{
path <- paste(dir, file, sep='//')
gr <- metabolicPathwayToGraph(path)
if (length(gr) > 0)
{
if (!expand)
{
adjMat <- removeCompoundsMetabolicGraph(gr)
}
else
{
adjMat <- removeCompoundsMetabolicGraph(gr)
adjMat <- expandMetabolicGraph(adjMat)
}
}
}
if ( ( type == 'Metabolic' && choice == 'relations' )
|| type == 'Non-Metabolic' )
{
path <- paste(dir, file, sep='//')
gr <- nonMetabolicPathwayToGraph(path, doubleEdges, groupMode)
if (!expand)
{
adjMat <- removeCompoundsNonMetabolicGraph(gr, unique=FALSE,
edgeTypes=edgeTypes)
}
else
{
adjMat <- removeCompoundsNonMetabolicGraph(gr, unique=FALSE,
edgeTypes=edgeTypes)
adjMat <- expandNonMetabolicGraph(adjMat)
}
}
return(adjMat)
}
#
# Find Graph Type
#
getPathwayType <- function(filepath, file)
{
types <- vector(mode='numeric', length=length(filepath))
for (i in 1:length(filepath))
{
num <- tail(unlist(strsplit(filepath[i], '//')), 1)
num <- as.numeric(gsub("[^0-9]", "", num))
if (num <= 2000) { type = 'Metabolic' }
if (num > 2000) { type = 'Non-Metabolic'}
types[i] <- type
}
return(types)
}
#
# Graph from Metabolic Pathways
#
metabolicPathwayToGraph <- function(filepath)
{
xmlDoc <- tryCatch(xmlTreeParse(filepath,error=NULL),
error=function(e) "error")
if(!('XMLDocument' %in% class(xmlDoc) )) { return() }
root <- xmlRoot(xmlDoc)
org <- xmlGetAttr(root,"org")
nodes <- as.vector(mapply(xmlName, root))
entryNodes <- root[which(nodes == 'entry')]
reactionNodes <- root[which(nodes == 'reaction')]
# Create vertices from entry nodes
idx <- sapply(1:length(entryNodes), function(x) x)
eid <- sapply(entryNodes, xmlGetAttr, "id")
enames <- gsub(paste(org,':',sep=''),'',
sapply(entryNodes, xmlGetAttr, "name"))
etype <- sapply(entryNodes, xmlGetAttr, "type")
vertices <- data.frame(ID=eid,id=eid,names=enames, type=etype,
stringsAsFactors=FALSE)
# Create edges from reaction nodes
edges <- list(); e <- 1
for (r in reactionNodes)
{
rids <- sapply(xmlChildren(r), xmlGetAttr, "id")
subsId <- which(names(rids) == "substrate")
prodId <- which(names(rids) == "product")
substrate <- list()
product <- list()
for (s in 1:length(subsId))
{ substrate[[s]] <- list(id=rids[subsId[s]]) }
for (p in 1:length(prodId))
{ product[[p]] <- list(id=rids[prodId[p]]) }
enzyme <- xmlGetAttr(r,"id")
substrateId <- unname(sapply(substrate, '[[', "id"))
productId <- unname(sapply(product, '[[', "id"))
# Non Reversible
for (i in 1:length(substrateId))
{ edges[[e]] <- c(substrateId[i], enzyme); e <- e + 1 }
for (i in 1:length(productId))
{ edges[[e]] <- c(enzyme, productId[i]); e <- e + 1 }
# Double the edges if reversible
if(xmlGetAttr(r,"type") == "reversible")
{
for (i in 1:length(productId))
{ edges[[e]] <- c(productId[i], enzyme); e <- e + 1 }
for (i in 1:length(substrateId))
{ edges[[e]] <- c(enzyme, substrateId[i]); e <- e + 1 }
}
}
if (length(edges) > 0 )
{
edges <- unique(data.frame(do.call(rbind, edges),
stringsAsFactors=FALSE))
names(edges) <- c('e1','e2')
}
res <- list(name=xmlGetAttr(root,"name"), edges=edges,vertices=vertices)
return(res)
}
removeCompoundsMetabolicGraph <- function(path)
{
nodeType <- 'gene'
if(path$name != gsub('ec','',path$name)) { nodeType<-"enzyme" }
enzymes <- which(path$vertices$type == nodeType)
vid <- path$vertices$id
entry1 <- c(); entry2 <- c()
if ( length(path$edges) > 0 )
{
# For each enzyme node find the neighbors.
# The neighbors that are of type 'compound' are to be removed, and
# newconnections have to be established with the appropriate enzymes.
for(j in 1:length(enzymes) )
{
L <- c(); R <- c();
ec <- vid[enzymes[j]]
# For each neighbor of the enzyme
for (r1 in path$edges[path$edges$e1 ==
path$vertices[,'id'][enzymes[j]],]$e2)
{
# if neighbor is a compound, find its neighbors
for (r2 in path$edges[path$edges$e1 ==
path$vertices[,'id'][which(vid == r1)],]$e2)
{
# for enzyme neighbors of the compound others than
# the initial enzyme
nid <- vid[which(path$vertices$id == r2)]
if (!(nid %in% R) && nid != ec)
{
L <- c(L,ec)
R <- c(R,nid)
}
}
}
entry1 <- c(entry1,L)
entry2 <- c(entry2,R)
}
}
# Construct the adjacency matrix
xid <- path$vertices$id[enzymes]
names <- path$vertices$names[enzymes]
adjMat <- matrix(rep(0,length(enzymes)^2), nrow=length(enzymes))
colnames(adjMat) <- names
rownames(adjMat) <- names
for(j in 1:length(entry1) )
{
adjMat[which(xid == entry1[j]), which(xid == entry2[j])] <- 1
}
return(adjMat)
}
expandMetabolicGraph <- function(adjMat)
{
names <- c()
Vcount <- nrow(adjMat)
Ecount <- sum(adjMat)
if (Vcount == 0) { return(NULL); }
n1 <- c(); n2 <- c()
for ( j in 1:nrow(adjMat) )
{
for ( z in 1:ncol(adjMat) )
{
if (adjMat[j,z] == 1)
{
n1 <- c(n1, colnames(adjMat)[j] )
n2 <- c(n2, colnames(adjMat)[z] )
}
}
}
# Expand gene names
for(j in 1:Vcount)
{
for(vk in unlist(strsplit(colnames(adjMat)[j]," ")) )
{
names <- c(names, vk)
}
}
names <- unique(names)
L <- c(); R <- c()
if (Ecount > 0)
{
for(j in 1:Ecount)
{
for(lm in unlist(strsplit(n1[j]," ")))
{
for(rn in unlist(strsplit(n2[j]," ")))
{
L <- c(L, lm)
R <- c(R, rn)
}
}
}
}
# Construct the adjacency matrix
N <- length(names)
adjMat <- matrix(rep(0,N^2), nrow=N)
for(j in 1:length(L) )
{
t <- 3 # Unknown
adjMat[which(names == L[j]), which(names == R[j])] <- t
}
colnames(adjMat) <- names
rownames(adjMat) <- names
# Remove self cycles
for(j in 1:nrow(adjMat) ) { adjMat[j,j] <- 0 }
return(adjMat)
}
#
# Graph from Mon Metabolic Pathways
#
nonMetabolicPathwayToGraph <- function(filepath, doubleEdges, groupMode)
{
xmlDoc <- tryCatch(xmlTreeParse(filepath,error=NULL),
error=function(e) "error")
if(!('XMLDocument' %in% class(xmlDoc) )) { return(NULL) }
# Create node families
root <- xmlRoot(xmlDoc)
org <- xmlGetAttr(root,"org")
nodes <- as.vector(mapply(xmlName, root))
entryNodes <- root[which(nodes == 'entry')]
type <- sapply(entryNodes, xmlGetAttr, "type")
groupNodes <- entryNodes[which(type == 'group')]
orthoNodes <- entryNodes[which(type != 'group')]
relationNodes <- root[which(nodes == 'relation')]
# Create vertices from entry nodes
vertices <- list()
vertices$id <- as.integer(unname(sapply(orthoNodes, xmlGetAttr, "id")))
vertices$names <- gsub(paste(org,':',sep=''), '',
unname(sapply(orthoNodes, xmlGetAttr, "name")))
vertices$type <- unname(sapply(orthoNodes, xmlGetAttr, "type"))
group <- list()
if (groupMode == 'expand')
{
# Create groups
for(gn in groupNodes)
{
group <- c( group,
list(sapply(xmlChildren(gn), xmlGetAttr, "id")) )
}
names(group) <- sapply(groupNodes, xmlGetAttr, "id")
}
if (groupMode == 'collapse')
{
# Replace group nodes with all genes of their components
for(gn in groupNodes)
{
entries <- unlist(lapply(xmlChildren(gn), xmlGetAttr, "id"))
genes <- vertices$names[which(vertices$id %in% entries)]
genes <- unique(unlist(lapply(as.list(genes),
function(x) { strsplit(x, ' ') } )))
genes <- paste(genes, collapse=' ')
vertices$id <- c(vertices$id, xmlGetAttr(gn, "id"))
vertices$names <- c(vertices$names, genes)
vertices$type <- c(vertices$type, "gene")
}
}
# Create relations
rentry1 <- sapply(relationNodes, xmlGetAttr, "entry1")
rentry2 <- sapply(relationNodes, xmlGetAttr, "entry2")
rtype <- sapply(relationNodes, xmlGetAttr, "type")
rents <- lapply(relationNodes, function(x) { xmlChildren(x) })
rsubtype <- list()
for(ent in rents)
{
subtype <- mapply(list, name='unknow', value='unknow', SIMPLIFY=FALSE)
if(length(ent) > 0)
{
X <- unname(sapply(ent, xmlGetAttr, "name"))
Y <- unname(sapply(ent, xmlGetAttr, "value"))
subtype <- mapply(list, name=X, value=Y, SIMPLIFY=FALSE)
}
rsubtype <- append(rsubtype, list(subtype))
}
bla <- function(e1, e2, name='unknow', type='noType', duplicate = FALSE)
{
L1 <- list(e1=e1, e2=e2, name=name, type=type)
L2 <- list(e1=e2, e2=e1, name=name, type=type)
if (!duplicate) { return( list( L1 )) }
if (duplicate) { return( list( L1, L2 )) }
}
# Create edges
E <- list(); i <- 0
for(subtypes in rsubtype)
{
i <- i + 1
inGroup <- FALSE
# type <- paste(names(subtypes), collapse='_')
if(length(group) != 0)
{
# If a node is of type group, then create all actual edges between
# its components and the other node.
GroupL <- groupL <- unlist(group[names(group) %in% rentry1[i]])
GroupR <- groupR <- unlist(group[names(group) %in% rentry2[i]])
if(length(groupL) == 0 && length(groupR) > 0)
{ GroupL <- rentry1[i] }
if(length(groupL) >0 && length(groupR) == 0)
{ GroupR <- rentry2[i] }
# Create an single edge by default; if the edge is of type
# compound, create the actual edges connecting the compounds.
# For an ambiguous edge type, create an edge in the other
# direction.
for(rn in subtypes)
{
dupl <- rn$name %in% doubleEdges
for(gl in GroupL)
{
for(gr in GroupR)
{
if (rn$name == "compound")
{
E <- c(E, bla(gl, rn$value, rn$name,
dup = dupl, type=rn$name))
E <- c(E, bla(rn$value, gr, rn$name,
dup = dupl, type=rn$name))
}
if (rn$name != "compound")
{
E <- c(E, bla(gl, gr, rn$name,
dup = dupl, type=rn$name))
}
}
}
if (length(groupL) >0 || length(groupR) > 0)
{
inGroup = TRUE
}
}
}
if (inGroup) { next() }
# No group nodes
for(rn in subtypes)
{
dupl <- rn$name %in% doubleEdges
if (rn$name == "compound")
{
E <- c(E, bla(rentry1[i],rn$value, dup=dupl, type=rn$name))
E <- c(E, bla(rn$value, rentry2[i], dup=dupl, type=rn$name))
}
if (rn$name != "compound")
{
E <- c(E, bla(rentry1[i], rentry2[i], rn$name,
dup = dupl, type=rn$name))
}
}
}
e1 <- sapply(E, function(x){ x$e1 })
e2 <- sapply(E, function(x){ x$e2 })
ename <- sapply(E, function(x){ x$name })
etype <- sapply(E, function(x){ x$type })
edges <- unique(data.frame(e1=e1, e2=e2, ename=ename, etype=etype))
if (nrow(edges) > 0)
{
edges <- list(e1=edges[,1], e2=edges[,2], type=edges[,3])
}
res <- list(vertices=vertices, edges=edges, name=xmlGetAttr(root,"name"))
return(res)
}
removeCompoundsNonMetabolicGraph <- function(path, unique, edgeTypes)
{
if (is.null(path)) return(NULL)
vid <- as.numeric(path$vertices$id)
etype <- path$vertices$type
nodeType <- 'gene'
if(path$name != gsub('ko','',path$name)) { nodeType <- "ortholog" }
source <- c(); destin <- c(); types <- c()
genesIndx <- which(path$vertices$type == nodeType)
for(gi in genesIndx)
{
# For each gene, find its neighboring vertices.
# KEGG entries are not always numbered successively.
L <- c(); R <- c(); TT <- c()
neighbors <- path$edges$e2[path$edges$e1 == vid[gi]]
for(neighbor in neighbors)
{
nbrId <- which( vid == neighbor )
# The neighbor is a gene which has yet to be added to
# the edgelist.
if( etype[nbrId] == nodeType && !(vid[nbrId] %in% R) )
{
# Connect the first gene with the neighbor
L <- c( L, vid[gi] )
R <- c( R, vid[nbrId] )
# Edges with more than one types have been stored seperately.
# Join all their types in a single entry the first time the
# edge has been found and make sure it is not added multiple
# times (2nd if clause).
idx1 <- which( path$edges$e1 == vid[gi] )
idx2 <- which( path$edges$e2 == vid[nbrId] )
idx <- intersect(idx1, idx2)
TT <- c( TT, paste((path$edges$type[idx]), collapse='_') )
}
# The neighbor is a compound.
if( etype[nbrId] == "compound" )
{
# The compound has to be removed, while the source gene is
# connected with the compound's neighboring gene.
cpdNeighbors <- path$edges$e2[
which(path$edges$e1 == vid[nbrId]) ]
for( cpdNeighbor in cpdNeighbors )
{
idx <- which( vid == cpdNeighbor )
# The compound's neighbor is a gene which has yet to be
# added to the edgelist.
if( etype[idx] == nodeType && !(vid[idx] %in% R) )
{
# Connect source gene with the neighbor
L <- c( L, vid[gi] )
R <- c( R, vid[idx] )
# The edgetype is 'compound'
TT <- c( TT, "compound")
}
}
}
}
source <- c( source, L )
destin <- c( destin, R )
types <- c( types, TT )
}
# Construct the adjacency matrix
if (unique)
{
# Recalculate indexes according to unique gene names
names <- unique(path$vertices$names[genesIndx])
adjMat <- matrix(rep(0,length(names)^2), nrow=length(names))
colnames(adjMat) <- names
rownames(adjMat) <- names
if (is.null(source) || is.null(destin))
{
return(adjMat)
}
for (i in 1:length(source))
{
idx1 <- which(path$vertices$id == source[i])
idx2 <- which(path$vertices$id == destin[i])
source[i] <- names[ names == path$vertices$names[idx1] ]
destin[i] <- names[ names == path$vertices$names[idx2] ]
}
for(j in 1:length(source) )
{
idx <- which(edgeTypes[,1] == types[j])
if (length(idx) == 0)
{
# Set new interaction types to apathetic
t <- 3
}
if (length(idx) > 0)
{
t <- edgeTypes[idx, 2]
}
adjMat[which(names == source[j]), which(names == destin[j])] <- t
}
}
else
{
# Construct the adjacency matrix
gids <- path$vertices$id[genesIndx]
names <- unname(path$vertices$names[genesIndx])
adjMat <- matrix(rep(0,length(genesIndx)^2),
nrow=length(genesIndx))
colnames(adjMat) <- names
rownames(adjMat) <- names
if (is.null(source) || is.null(destin))
{
return(adjMat)
}
for(j in 1:length(source) )
{
idx <- which(edgeTypes[,1] == types[j])
if (length(idx) == 0)
{
t <- 3; # New interaction type
}
if (length(idx) > 0)
{
t <- edgeTypes[idx, 2]
}
adjMat[which(gids == source[j]), which(gids == destin[j])] <- t
}
}
# Remove self loops
for (j in 1:nrow(adjMat)) { adjMat[j,j] <- 0 }
return(adjMat)
}
expandNonMetabolicGraph <- function(adjMat)
{
if (!is.matrix(adjMat)) return(NULL)
names <- c()
Vcount <- nrow(adjMat)
Ecount <- sum(adjMat)
if (Vcount == 0) { return(NULL); }
n1 <- c(); n2 <- c(); t <- c()
for ( j in 1:nrow(adjMat) )
{
for ( z in 1:ncol(adjMat) )
{
if (adjMat[j,z] > 0)
{
n1 <- c(n1, colnames(adjMat)[j] )
n2 <- c(n2, colnames(adjMat)[z] )
t <- c(t, adjMat[j,z])
}
}
}
# Expand gene names
names <- unique(unlist(lapply(colnames(adjMat),
function(x) {strsplit(x,' ')} )))
L <- c(); R <- c(); TT <- c()
if (Ecount > 0)
{
for(j in 1:Ecount)
{
l1 <- unlist(strsplit(n1[j],' '))
l2 <- unlist(strsplit(n2[j],' '))
for(lm in l1)
{
for(rn in l2)
{
L <- c(L, lm)
R <- c(R, rn)
TT <- c(TT, t[j])
}
}
}
}
L <- if(!is.null(L)) { L <- na.omit((L)) }
R <- if(!is.null(L)) { R <- na.omit((R)) }
TT <- if(!is.null(TT)) { TT <- na.omit((TT)) }
# Construct the adjacency matrix
N <- length(names)
adjMat <- matrix(rep(0,N^2), nrow=N)
for(j in 1:length(L) )
{
adjMat[which(names == L[j]), which(names == R[j])] <- TT[j]
}
colnames(adjMat) <- names
rownames(adjMat) <- names
# Remove self cycles
for(j in 1:nrow(adjMat) ) { adjMat[j,j] <- 0 }
return(adjMat)
}
getEdgeTypes <- function(type)
{
# noEdge 0
# activation 1
# inhibition 2
# apathetic 3
data = c(
'unknow', 3,
'activation', 1,
'inhibition', 2,
'binding/association', 3,
'expression', 1,
'repression', 2,
'phosphorylation', 3, #1
'dephosphorylation', 3,
'ubiquitination', 3,
'dissociation', 3,
'indirect effect', 3, #1
'state change', 3,
'compound', 3, #1
'hidden compound', 3,
'missing interaction', 3,
'activation_phosphorylation', 1,
'activation_dephosphorylation', 1,
'activation_ubiquitination', 1,
'activation_indirect effect', 1,
'activation_binding/association', 1,
'activation_inhibition', 3,
'activation_methylation', 1,
'activation_phosphorylation_binding/association', 1,
'activation_phosphorylation_indirect effect', 1,
'inhibition_phosphorylation', 2,
'inhibition_dephosphorylation', 2,
'inhibition_ubiquitination', 2,
'inhibition_indirect effect', 2,
'inhibition_binding/association', 2,
'inhibition_expression', 2,
'inhibition_methylation', 2,
'compound_expression', 1,
'compound_activation', 1,
'compound_inhibition', 2,
'compound_activation_indirect effect', 1,
'compound_activation_phosphorylation', 1,
'phosphorylation_indirect effect', 3,
'phosphorylation_binding/association', 3,
'phosphorylation_dissociation', 3,
'dephosphorylation_indirect effect', 3,
'binding/association_missing interaction', 3,
'binding/association_indirect effect', 3,
'expression_indirect effect', 1,
'repression_indirect effect', 2,
'ubiquitination_inhibition', 2,
'dissociation_missing interaction', 3,
'indirect effect_phosphorylation', 3,
'inhibition_dephosphorylation_indirect effect', 3, #new
'inhibition_glycosylation',3, #new
'glycosylation',3 #new
)
E <- as.numeric(data[seq(2,length(data),2)])
names(E) <- data[seq(1,length(data),2)]
if (!missing(type))
{
return(E[type])
}
if (missing(type))
{
df <- data.frame(names(E),E)
rownames(df) <- 1:nrow(df)
colnames(df) <- c('Edge', 'Type')
return(df)
}
return( E[type] )
}
getDoubleEdges <- function()
{
doubleEdges <- c('compound',
'binding/association',
'dissociation',
'dissociation_missing interaction',
'state change',
'binding/association_missing interaction',
'missing interaction', 'hidden compound')
return(doubleEdges)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.