# server.R
shinyServer(function(input, output, session) {
# Database of choice
# This could be loaded in global.R to save memory, but
# this way each user can load a different database
FELLA.DATA <- reactive({
if (input$database != "") {
withProgress(message = "Loading database", value = .5, {
ans <- loadKEGGdata(
databaseDir = input$database,
internalDir = FALSE,
loadMatrix = c("diffusion", "pagerank")
)
incProgress(amount = .5, message = "Done")
})
ans
}
})
# database summary
output$databaseInfo <- renderText({
data <- FELLA.DATA()
if (is.null(data)) {
c(
"Database directory is empty...",
"\nMake sure you executed the following",
"\nat least once after installing FELLA:",
"\nbuildGraphFromKEGGREST",
"\nbuildDataFromGraph")
} else {
comment(FELLA:::getGraph(data))
}
})
# First step: create the USER variable
createUser <- reactive({
if (input$radioInput == 1) {
read.comp <- readLines("examples/input_1_compounds.list")
} else if (input$radioInput == 2) {
read.comp <- readLines("examples/input_2_compounds.list")
} else if (input$radioInput == 3) {
read.comp <- readLines("examples/input_3_metaboanalyst.list")
} else {
if (!is.null(input$file)) {
read.file <- read.table(
input$file$datapath,
header = FALSE,
stringsAsFactors = FALSE)
read.comp <- as.character(read.file[, 1])
read.comp <- read.comp[complete.cases(read.comp)]
if (is.null(read.comp)) {
return(NULL)
}
}
else {
message("No compounds uploaded yet.")
return(NULL)
}
}
data <- FELLA.DATA()
if (is.null(data)) return(NULL)
withProgress(message = "Running enrichment", value = .5, {
result <- enrich(
compounds = read.comp,
method = input$method,
approx =input$approx,
niter = input$niter,
data = data)
incProgress(amount = .5, message = "Done")
})
return(result)
})
# Show the user how the file looks like
output$exampleInput <- renderText(
paste(
readLines("examples/input_2_compounds.list"),
collapse = "\n"
)
)
# Second: the summary of the compounds in the input:
# read names, mapped and unmapped metabolites
inputSummary <- reactive({
data <- FELLA.DATA()
if (!is.null(createUser()) & !is.null(data)) {
input <- getInput(createUser())
inputNames <- getName(data, input)
inputNames <- sapply(inputNames, function(x) {
if (length(x)) {
return(x[[1]])}
return(NULL)
})
excluded <- getExcluded(createUser())
return(list("input" = input,
"inputNames" = inputNames,
"excluded" = excluded))
}
})
# Downloadable example file
output$downloadExample <- downloadHandler(
filename = function() {
"example2.txt"
},
content = function(file) {
con <- readLines("examples/input_2_compounds.list")
write(con, file)
},
contentType = "text"
)
# Table showing current compounds
output$tableCompounds <- renderTable({
if (!is.null(inputSummary())) {
outTable <- cbind(inputSummary()$inputNames)
colnames(outTable) <- "KEGG name"
return(outTable)
}
})
# Table showing excluded compounds
output$tableExcluded <- renderTable({
if (!is.null(inputSummary())) {
if (length(inputSummary()$excluded) > 0) {
outTable <- data.frame(inputSummary()$excluded)
names(outTable) <- "KEGG id"
return(outTable)
}
}
})
# Generate the graph
# The current graph is extracted using another function, though,
# because the current graph can vary with the user-selected
# GO term, if any
generateGraph <- reactive({
usr <- createUser()
data <- FELLA.DATA()
if (!is.null(usr) & !is.null(data)) {
return(
generateResultsGraph(
object = usr,
method = input$method,
threshold = input$threshold,
plimit = 15,
nlimit = input$nlimit,
thresholdConnectedComponent = input$thresholdConnectedComponent,
LabelLengthAtPlot = input$LabelLengthAtPlot,
data = data))
}
})
# This function returns the currently chosen graph connected component
currentGraph <- reactive({
if (!is.null(createUser())) {
g <- generateGraph()
# GO tag?
orgDb <- input$GOorgDb
ont <- input$GOOntology
biomart <- input$GObiomart
dataset <- input$GOdataset
if (input$GOTermInput != "" &
input$method != "hypergeom" &
!is.null(orgDb) &
!is.null(ont) &
!is.null(biomart) &
!is.null(dataset)) {
withProgress(message = "Adding GO term legend", value = .5, {
g_go <- addGOToGraph(
graph = g,
GOterm = input$GOTermInput,
godata.options = list(
OrgDb = orgDb,
ont = ont
),
mart.options = list(
biomart = biomart,
dataset = dataset
)
)
incProgress(amount = .5, message = "Done")
})
return(g_go)
}
return(g)
}
return(NULL)
})
# Tooltip about the current graph size
output$graphSize <- renderText({
if (!is.null(createUser())) {
g <- currentGraph()
if (!is.null(g)) {
txt <- paste0("Number of nodes: ", vcount(g))
if (input$GOTermInput != "") {
txt <- paste(
txt,
"Legend for GO term similarity:",
" (low) yellow < orange < red < purple (high)",
sep = "\n"
)
}
return(txt)
} else {
return("Graph is NULL! No significant pathways have been found.")
}
}
})
# ---------------------------------------------------
# Table of results
output$tableSolution <- DT::renderDataTable({
data <- FELLA.DATA()
user <- createUser()
g <- currentGraph()
if (!is.null(data) & !is.null(g) & is.igraph(g)) {
if (vcount(g) == 0) return(NULL)
wholeTable <- generateResultsTable(
object = user,
method = input$method,
threshold = input$threshold,
plimit = 15,
nlimit = input$nlimit,
LabelLengthAtPlot = 100,
data = data)
# Only nodes in graph
plottedRows <- wholeTable$"KEGG.id" %in% V(g)$name
outTable <- wholeTable[plottedRows, ]
rownames(outTable) <- NULL
# Add hyperlinks to KEGG
outTable$"KEGG.id" <- paste0(
"<a href=\"http://www.genome.jp/dbget-bin/www_bget?",
outTable$"KEGG.id", "\"", "\ target=\"_blank",
"\">", outTable$"KEGG.id", "</a>")
escape <- which(colnames(outTable) == "KEGG.id")
DT::datatable(outTable,
escape = escape,
options = list(pageLength = 100)) %>%
DT::formatSignif(columns = "p.score", digits = 2)
}
})
# ---------------------------------------------------
# CC example: change default value for the updateTextInput!
observe({
if (input$exampleGOCC > 0) {
updateTextInput(session, "GOTermInput", value = "GO:0005739")
updateTextInput(session, "GOorgDb", value = "org.Hs.eg.db")
updateSelectInput(session, "GOOntology", selected = "CC")
updateTextInput(session, "GObiomart", value = "ensembl")
updateTextInput(session, "GOdataset", value = "hsapiens_gene_ensembl")
}
})
###########################################################
# network as a list with nodes and edges
network <- reactive({
g <- currentGraph()
if (!is.null(g)) {
id <- V(g)$name
label <- V(g)$label
nodes <- data.frame(id, label, stringsAsFactors = FALSE)
# GO labels?
if ("GO.simil" %in% list.vertex.attributes(g)) {
GO.simil <- unlist(V(g)$GO.simil)
GO.annot <- TRUE
} else {
GO.annot <- FALSE
}
map.com <- c("pathway", "module", "enzyme", "reaction", "compound")
map.color <- c("#E6A3A3", "#E2D3E2", "#DFC1A3", "#D0E5F2", "#A4D4A4")
map.labelcolor <- c("#CD0000", "#CD96CD", "#CE6700",
"#8DB6CD", "#548B54")
map.nodeWidth <- c(40, 30, 25, 22, 22)
nodeShape <- ifelse(
V(g)$name %in% getInput(createUser()),
"box",
"ellipse"
)
nodes$group <- map.com[V(g)$com]
nodes$color <- map.color[V(g)$com]
# width
nodes$value <- map.nodeWidth[V(g)$com]
nodes$shape <- nodeShape
# Change color and label if GO annotations are present
if (GO.annot) {
ids <- !is.na(GO.simil)
GO.semsim <- GO.simil[ids]
GO.hits <- names(GO.semsim)
if (!is.null(GO.hits)) {
newColor <- sapply(
GO.semsim,
function(x) {
if (x < 0.5) return("#FFD500")
else if (x < 0.7) return("#FF5500")
else if (x < 0.9) return("#FF0000")
return("#B300FF")
}
)
newName <- paste0(nodes$label[ids], "[", GO.hits, "]")
newShape <- "triangle"
# modify name and color
nodes$label[ids] <- newName
nodes$color[ids] <- newColor
nodes$shape[ids] <- newShape
}
}
# tooltip
nodeLink <- paste0(
"<a href=\"http://www.genome.jp/dbget-bin/www_bget?",
V(g)$name, "\"", "\ target=\"_blank", "\">", V(g)$name, "</a>")
if(vcount(g) == 0) nodeLink <- character(0)
nodes$title <- nodeLink
source <- V(g)[get.edgelist(g)[, 1]]$name
target <- V(g)[get.edgelist(g)[, 2]]$name
edges <- data.frame(source, target, stringsAsFactors = FALSE)
names(edges) <- c("from", "to")
network <- list(
nodes = nodes,
edges = edges)
return(network)
}
return(NULL)
})
output$cytoscapePlot <- renderVisNetwork({
net <- network()
if (!is.null(net)) {
visNetwork(nodes = net$nodes, edges = net$edges) %>%
visIgraphLayout() %>%
visEdges(smooth = FALSE) %>%
visOptions(
selectedBy = "group",
nodesIdSelection = TRUE,
highlightNearest = TRUE)
}
})
###########################################################
output$exportResults_csv <- downloadHandler(
filename = function() {
"resultsTable.csv"
},
content = function(file) {
data <- FELLA.DATA()
if (!is.null(data)) {
exportResults(
format = "csv",
file = file,
object = createUser(),
method = input$method,
threshold = input$threshold,
nlimit = input$nlimit,
plimit = 15,
data = data)
}
},
contentType = "text/csv"
)
tableEnzymes <- reactive({
user <- createUser()
data <- FELLA.DATA()
if (!is.null(user) & !is.null(data)) {
generateEnzymesTable(
object = user,
method = input$method,
threshold = input$threshold,
nlimit = input$nlimit,
data = data,
mart.options = NULL)
}
})
output$exportEnzymes_csv <- downloadHandler(
filename = function() {
"enzymesTable.csv"
},
content = function(file) {
tab <- tableEnzymes()
if (!is.null(tab)) {
write.csv(
x = tab,
file = file,
row.names = FALSE
)
}
},
contentType = "text/csv"
)
output$exportEnzymes_genelist <- downloadHandler(
filename = function() {
"genesFromEnzymes.txt"
},
content = function(file) {
tab <- tableEnzymes()
if (!is.null(tab)) {
writeLines(
text = unique(unlist(strsplit(tab$Genes, split = ";"))),
con = file
)
}
},
contentType = "text"
)
output$exportigraph <- downloadHandler(
filename = function() {
"resultsSubgraph.RData"
},
content = function(file) {
data <- FELLA.DATA()
if (!is.null(data)) {
exportResults(
format = "igraph",
file = file,
object = createUser(),
method = input$method,
threshold = input$threshold,
thresholdConnectedComponent = input$thresholdConnectedComponent,
nlimit = input$nlimit,
plimit = 15,
data = data)
}
}
)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.