#'Query networks containing one or several relationship types from the database
#'@description query networks of a relationship pattern that contains the given \code{from} and/or \code{to} nodes using neo4j id, see details.
#'@usage fetchHetNetwork(from, to, pattern, returnas)
#'@param from a character vector of start nodes e.g. from = c('id1', 'id2'). Given \code{from} = NULL, will result in all possible start nodes.
#'Otherwise the value must be a neo4j id, see details and see \code{\link{convertId}} for how to convert ids.
#'@param to a character vector of end nodes e.g. to = c('id1', 'id2'). Given \code{to} = NULL, will result in all possible end nodes, see \code{from} for details.
#'@param pattern a string specifying the relationship pattern.
#'
#'Providing a node as \code{(from:Nodetype)} is to specify the start node.
#'Providing a node as \code{(to:Nodetype)} is to specify the end node.
#'Providing a node as \code{(:Nodetype)} means any node of the given node type.
#'
#'A relationship type is indicated by a pair of square brackets between the arrow e.g. \code{-[:RELATIONSHIP_TYPE]->}
#'
#'@param returnas a string specifying output type. It can be one of dataframe, list, json. Default is dataframe.
#'@details The function is used to query networks containing one or more relationship types (heterogeneous network). Use \code{\link{fetchNetwork}} to query networks containing one relationship type.
#'
#'The database uses two id systems. The neo4j id is a numeric, internal id automatically generated by the database system.
#'The grinn id (gid) is an id system of Grinn database that uses main ids of standard resources
#'i.e. ENSEMBL for genes (e.g.ENSG00000139618), UniProt for proteins (e.g.P0C9J6), PubChem CID for compounds (e.g.5793), KEGG for pathways (e.g.hsa00010).
#'@return list of network information with the following components:
#'
#'nodes:
#'
#'\code{id} = node neo4j id
#'
#'\code{gid} = node grinn id
#'
#'\code{nodename} = node name
#'
#'\code{nodelabel} = node type
#'
#'\code{nodexref} = node cross references
#'
#'edges:
#'
#'\code{source, target} = node neo4j id
#'
#'\code{type} = relationship type
#'
#'\code{datasource} = relationship resource
#'
#'\code{properties} = relationship properties
#'
#'Return empty list if error or found nothing.
#'@author Kwanjeera W \email{kwanich@@ucdavis.edu}
#'@seealso \code{\link{convertId}}, \code{\link{fetchNetworkByGID}}
#'
#'For database structure see \url{http://grinnhomepage}
#'@examples
#'# Query the network of (from:Compound)-BIOCHEMICAL_REACTION->(to:Compound)<-ANNOTATION-(:Pathway)
#'#from = list(7097,41074,39189) #list of neo4j ids
#'#to = list(113,2440,554,102) #list of neo4j ids
#'#pattern = "(from:Compound)-[:BIOCHEMICAL_REACTION]->(to:Compound)<-[:ANNOTATION]-(:Pathway)"
#'#result = fetchHetNetwork(from=from, to=to, pattern=pattern)
#'@export
fetchHetNetwork <- function(from=NULL, to=NULL, pattern, returnas="dataframe") UseMethod("fetchHetNetwork")
#'@export
fetchHetNetwork.default <- function(from=NULL, to=NULL, pattern, returnas="dataframe"){
out <- tryCatch(
{
if (!is.character(pattern)) stop("argument 'pattern' must be a character vector")
if (length(from) == 0) from = NULL #reset empty list to NULL
if (length(to) == 0) to = NULL #reset empty list to NULL
#construct query
maxkw = 500 #maximum keywords
doPar = FALSE
if (!is.null(from) && !is.null(to)) {
querystring = pathsList["fromto"]
doPar = TRUE #do loop
from = unique(stringr::str_trim(unlist(from))) #remove whiteline, duplicate
from = from[!is.na(suppressWarnings(as.numeric(from)))] #remove string, ID accepts integer only
to = unique(stringr::str_trim(unlist(to))) #remove whiteline, duplicate
to = to[!is.na(suppressWarnings(as.numeric(to)))] #remove string, ID accepts integer only
}else if (!is.null(from) && is.null(to)) {
querystring = pathsList["from"]
txtinput = unique(stringr::str_trim(unlist(from))) #remove whiteline, duplicate
txtinput = txtinput[!is.na(suppressWarnings(as.numeric(txtinput)))] #remove string, ID accepts integer only
len = length(txtinput)
}else if (is.null(from) && !is.null(to)) {
querystring = pathsList["to"]
txtinput = unique(stringr::str_trim(unlist(to))) #remove whiteline, duplicate
txtinput = txtinput[!is.na(suppressWarnings(as.numeric(txtinput)))] #remove string, ID accepts integer only
len = length(txtinput)
}else{
stop("Error: No query provided")
}
querystring = gsub("relpattern", pattern, querystring)
cat("Querying network ...\n")
if(!doPar){
if(len <= maxkw){
qstring = gsub("keyword", paste0("['",paste0(txtinput, collapse = "','"),"']"), querystring)
cat(qstring,"\n")
paths = curlRequest.TRANSACTION(cypher=qstring)
}else{
cat("Split queries for more than 500 nodes ...\nWarning: querying a large number of nodes will take long time. \n")
# subinp = split(txtinput, ceiling(seq_along(txtinput)/maxkw)) #split keywords
# paths = foreach(i=1:length(subinp), .combine=c) %dopar% {
# qstring = gsub("keyword", paste0("['",paste0(unlist(subinp[i]), collapse = "','"),"']"), querystring)
# cat(qstring,"\n")
# curlRequest.TRANSACTION(cypher=qstring)
# }
paths = lapply(txtinput, function (x) curlRequest.TRANSACTION(cypher=gsub("keyword", paste0("['",paste0(x, collapse = "','"),"']"), querystring)))
paths = unlist(paths, recursive = FALSE)
}
}else{
cat("Querying from combination of nodes ...\nWarning: querying a large number of nodes will take long time. \n")
# path = foreach(i=1:length(from), .combine=rbind) %dopar% {
# foreach(j=1:length(to)) %dopar% {
# qstring = gsub("keyfrom", from[i], querystring)
# qstring = gsub("keyto", to[j], qstring)
# cat(qstring,"\n")
# curlRequest.TRANSACTION(cypher=qstring)
# }
# }
# paths = unlist(path, recursive = FALSE)
ft = expand.grid(from,to)
path = apply(ft, 1, function (x) curlRequest.TRANSACTION(cypher=gsub("keyfrom", x[1], gsub("keyto", x[2], querystring))))
paths = unlist(path, recursive = FALSE)
}
network = formatNetworkOutput(paths)
networknode = network$nodes
out = switch(returnas,
dataframe = list(nodes=networknode, edges=network$edges),
list = list(nodes = split(networknode, seq(nrow(networknode))), edges = split(network$edges, seq(nrow(network$edges)))),
json = list(nodes=jsonlite::toJSON(networknode), edges=jsonlite::toJSON(network$edges)),
stop("incorrect return type"))
},error=function(e) {
message(e)
cat("\nError: RETURN no network ..\n")
out = switch(returnas,
dataframe = list(nodes = data.frame(), edges = data.frame()),
list = list(nodes = list(), edges = list()),
json = list(nodes = "", edges = ""))
})
return(out)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.