Nothing
#' @import bnlearn
#' @import heatmaply
#' @import plotly
#' @import rintrojs
#' @import shiny
#' @import shinyAce
#' @import shinydashboard
#' @import shinyWidgets
options(shiny.testmode=TRUE)
# Define required server logic
shinyServer(function(input, output, session) {
# Get the data selection from user
dat <- shiny::reactive({
if (input$dataInput == 1) {
if (input$net == 1) {
dat <- learning.test
} else if (input$net == 2) {
dat <- gaussian.test
} else if (input$net == 3) {
dat <- alarm
} else if (input$net == 4) {
dat <- insurance
} else if (input$net == 5) {
dat <- hailfinder
}
} else if (input$dataInput == 2) {
# Get the uploaded file from user
inFile <- input$file
if (is.null(inFile))
return(NULL)
dat <- read.csv(inFile$datapath)
}
})
# bnlearn no longer supports character vars.
# Temp step to convert character to factor
# dat <- shiny::reactive({
# dat <- dplyr::mutate_if(dat0(), is.character, as.factor)
# })
# Learn the structure of the network
dag <- shiny::reactive({
if (is.null(dat()))
return(NULL)
# Create a Progress object
progress <- shiny::Progress$new()
# Make sure it closes when we exit this reactive, even if there's an error
on.exit(progress$close())
progress$set(message = "Learning network structure", value = 0)
# Get the selected learning algorithm from the user and learn the network
if (input$alg == "gs") {
dag <- bnlearn::cextend(bnlearn::gs(dat()), strict = FALSE)
} else if (input$alg == "iamb") {
dag <- bnlearn::cextend(bnlearn::iamb(dat()), strict = FALSE)
} else if (input$alg == "fast.iamb") {
dag <- bnlearn::cextend(bnlearn::fast.iamb(dat()), strict = FALSE)
} else if (input$alg == "inter.iamb") {
dag <- bnlearn::cextend(bnlearn::inter.iamb(dat()), strict = FALSE)
} else if (input$alg == "hc") {
dag <- bnlearn::cextend(bnlearn::hc(dat()), strict = FALSE)
} else if (input$alg == "tabu") {
dag <- bnlearn::cextend(bnlearn::tabu(dat()), strict = FALSE)
} else if (input$alg == "mmhc") {
dag <- bnlearn::cextend(bnlearn::mmhc(dat()), strict = FALSE)
} else if (input$alg == "rsmax2") {
dag <- bnlearn::cextend(bnlearn::rsmax2(dat()), strict = FALSE)
} else if (input$alg == "mmpc") {
dag <- bnlearn::cextend(bnlearn::mmpc(dat()), strict = FALSE)
} else if (input$alg == "si.hiton.pc") {
dag <- bnlearn::cextend(bnlearn::si.hiton.pc(dat()), strict = FALSE)
} else if (input$alg == "aracne") {
dag <- bnlearn::cextend(bnlearn::aracne(dat()), strict = FALSE)
} else if (input$alg == "chow.liu") {
dag <- bnlearn::cextend(bnlearn::chow.liu(dat()), strict = FALSE)
}
})
# Create the nodes value box
output$nodesBox <- shiny::renderUI({
if (is.null(dat()))
return(NULL)
# Get the number of nodes in the network
nodes <- bnlearn::nnodes(dag())
shinydashboard::valueBox(nodes,
"Nodes",
icon = shiny::icon("circle"),
color = "blue")
})
# Create the arcs value box
output$arcsBox <- renderUI({
if (is.null(dat()))
return(NULL)
# Get the number of arcs in the network
arcs <- bnlearn::narcs(dag())
shinydashboard::valueBox(arcs,
"Arcs",
icon = shiny::icon("arrow-right"),
color = "green")
})
# Observe intro btn and start the intro
shiny::observeEvent(input$homeIntro,
rintrojs::introjs(session, options = list(steps = homeHelp))
)
# Plot the d3 force directed network
output$netPlot <- networkD3::renderSimpleNetwork({
if (is.null(dat()))
return(NULL)
# Get the arc directions
networkData <- data.frame(bnlearn::arcs(dag()))
networkD3::simpleNetwork(
networkData,
Source = "from",
Target = "to",
opacity = 0.75,
zoom = TRUE
)
})
# Print the network score
output$score <- shiny::renderText({
if (bnlearn::directed(dag())) {
# If all of the data is numeric,...
if (all(sapply(dat(), is.numeric))) {
# Get the selected score function from the user and calculate the score
if (input$type == "loglik") {
bnlearn::score(dag(), dat(), type = "loglik-g")
} else if (input$type == "aic") {
bnlearn::score(dag(), dat(), type = "aic-g")
} else if (input$type == "bic") {
bnlearn::score(dag(), dat(), type = "bic-g")
} else {
bnlearn::score(dag(), dat(), type = "bge")
}
}
# If the data is discrete,...
else {
if (input$type == "loglik") {
bnlearn::score(dag(), dat(), type = "loglik")
} else if (input$type == "aic") {
bnlearn::score(dag(), dat(), type = "aic")
} else if (input$type == "bic") {
bnlearn::score(dag(), dat(), type = "bic")
} else {
bnlearn::score(dag(), dat(), type = "bde")
}
}
} else
shiny::validate(
shiny::need(
try(score != "")
,
"Make sure your network is completely directed in order to view your network's score..."
)
)
})
# Observe intro btn and start the intro
shiny::observeEvent(input$structureIntro,
rintrojs::introjs(session, options = list(steps = structureHelp))
)
# Fit the model parameters
fit <- shiny::reactive({
if (is.null(dat()))
return(NULL)
if (bnlearn::directed(dag())) {
if (all(sapply(dat(), is.numeric))) met = "mle-g"
else met = input$met
# Get the selected parameter learning method from the user and learn the paramaters
fit <- bnlearn::bn.fit(dag(), dat(), method = met)
}
})
# # Create data frame for selected parameter
# param <- shiny::reactive({
# param <- data.frame(coef(fit()[[input$Node]]))
# if (is.numeric(dat()[,1])) {
# colnames(param) <- "Param"
# param <- cbind(param = rownames(param), param)
# param[,"Param"] <- round(param[,"Param"], digits = 3)
# param <- transform(param, Param = as.numeric(Param))
# } else {
# param[,"Freq"] <- round(param[,"Freq"], digits = 3)
# param <- transform(param, Freq = as.numeric(Freq))
# }
# })
# # Plot Handsontable for selected parameter
# values = shiny::reactiveValues()
# setHot = function(x) values[["hot"]] <<- x
# output$hot = rhandsontable::renderRHandsontable({
# if (!is.null(input$hot)) {
# DF = rhandsontable::hot_to_r(input$hot)
# } else {
# DF = param()
# }
# if (is.numeric(dat()[,1])) {
# col <- "Param"
# } else {
# col <- "Freq"
# }
# setHot(DF)
# rhandsontable::rhandsontable(DF, readOnly = TRUE, rowHeaders = NULL) %>%
# rhandsontable::hot_table(highlightCol = TRUE, highlightRow = TRUE) %>%
# rhandsontabl::hot_context_menu(allowRowEdit = FALSE, allowColEdit = FALSE) %>%
# rhandsontable::hot_col(col, readOnly = FALSE)
# })
#
# # Add expert knowledge to the model
# expertFit <- shiny::reactive({
# if (!is.null(values[["hot"]])) {
# expertFit <- fit()
# temp <- data.frame(values[["hot"]])
# if (is.numeric(dat()[,1])) {
# stdev <- as.numeric(fit()[[input$Node]]["sd"])
# expertFit[[input$Node]] <- list(coef = as.numeric(temp[,"Param"]), sd = stdev)
# } else {
# cpt <- coef(expertFit()[[input$Node]])
# cpt[1:length(param()[,"Freq"])] <- as.numeric(temp[,"Freq"])
# expertFit[[input$Node]] <- cpt
# }
# } else {
# expertFit <- fit()
# }
# })
# Set the parameter graphic options
graphic <- shiny::reactive({
# If data is continuous, ...
if (all(sapply(dat(), is.numeric))) {
graphic <- c("Histogram" = "histogram",
"XY Plot" = "xyplot",
"QQ Plot" = "qqplot")
# If data is discrete,...
} else {
graphic <- c("Bar Chart" = "barchart",
"Dot Plot" = "dotplot")
}
})
# Send the parameter choices to the user
shiny::observe({
shiny::updateSelectInput(session, "param", choices = graphic())
})
# Send the node choices to the user
shiny::observe({
shiny::updateSelectInput(session, "Node", choices = colnames(dat()))
})
# Plot the model parameters
output$condPlot <- shiny::renderPlot({
if (is.null(dat()))
return(NULL)
if (bnlearn::directed(dag())) {
# Get the selected graphic from the user and plot the parameters
if (input$param == "histogram") {
bnlearn::bn.fit.histogram(fit())
} else if (input$param == "xyplot") {
bnlearn::bn.fit.xyplot(fit())
} else if (input$param == "qqplot") {
bnlearn::bn.fit.qqplot(fit())
} else if (input$param == "barchart") {
bnlearn::bn.fit.barchart(fit()[[input$Node]])
} else if (input$param == "dotplot") {
bnlearn::bn.fit.dotplot(fit()[[input$Node]])
}
} else
shiny::validate(
shiny::need(
try(condPlot != "")
,
"Make sure your network is completely directed in order to view the parameter infographics..."
)
)
})
# Observe intro btn and start the intro
shiny::observeEvent(input$parametersIntro,
rintrojs::introjs(session, options = list(steps = parametersHelp))
)
# Send the evidence node choices to the user
shiny::observe({
shiny::updateSelectInput(session, "evidenceNode", choices = names(dat()))
})
# Send the evidence choices to the user
shiny::observe({
whichNode <- which(colnames(dat()) == input$evidenceNode)
evidenceLevels <- as.vector(unique(dat()[,whichNode]))
shiny::updateSelectInput(session, "evidence", choices = evidenceLevels)
})
# Send the event node choices to the user
shiny::observe({
shiny::updateSelectInput(session, "event", choices = names(dat()))
})
# Perform Bayesian inference based on evidence and plot results
output$distPlot <- shiny::renderPlot({
if (is.null(dat()))
return(NULL)
if (all(sapply(dat(), is.numeric)))
shiny::validate(
shiny::need(
try(distPlot != ""),
"Inference is currently not supported for continuous variables..."
)
)
# Create a string of the selected evidence
str1 <<- paste0("(", input$evidenceNode, "=='", input$evidence, "')")
# Estimate the conditional PD and tabularize the results
nodeProbs <- prop.table(table(bnlearn::cpdist(fit(), input$event, eval(parse(text = str1)))))
# Create a bar plot of the conditional PD
barplot(
nodeProbs,
col = "lightblue",
main = "Conditional Probabilities",
border = NA,
xlab = "Levels",
ylab = "Probabilities",
ylim = c(0, 1)
)
})
# Observe intro btn and start the intro
shiny::observeEvent(input$inferenceIntro,
rintrojs::introjs(session, options = list(steps = inferenceHelp))
)
# Send the node names to the user
shiny::observe({
shiny::updateSelectInput(session, "nodeNames", choices = colnames(dat()))
})
# Get the selected node measure from the user and print the results
output$nodeText <- shiny::renderText({
if (is.null(dat()))
return(NULL)
if (input$nodeMeasure == "mb") {
bnlearn::mb(dag(), input$nodeNames)
} else if (input$nodeMeasure == "nbr") {
bnlearn::nbr(dag(), input$nodeNames)
} else if (input$nodeMeasure == "parents") {
bnlearn::parents(dag(), input$nodeNames)
} else if (input$nodeMeasure == "children") {
bnlearn::children(dag(), input$nodeNames)
} else if (input$nodeMeasure == "in.degree") {
bnlearn::in.degree(dag(), input$nodeNames)
} else if (input$nodeMeasure == "out.degree") {
bnlearn::out.degree(dag(), input$nodeNames)
} else if (input$nodeMeasure == "incident.arcs") {
bnlearn::incident.arcs(dag(), input$nodeNames)
} else if (input$nodeMeasure == "incoming.arcs") {
bnlearn::incoming.arcs(dag(), input$nodeNames)
} else if (input$nodeMeasure == "outgoing.arcs") {
bnlearn::outgoing.arcs(dag(), input$nodeNames)
} else
bnlearn::incident.arcs(dag(), input$nodeNames)
})
# Get the selected network measure from the user and plot the results
output$netTable <- plotly::renderPlotly({
if (is.null(dat()))
return(NULL)
# Plot a d3 heatmap of the adjacency matrix
heatmaply::heatmaply(
bnlearn::amat(dag()),
grid_gap = 1,
colors = blues9,
dendrogram = input$dendrogram,
symm = TRUE,
margins = c(100, 100, NA, 0),
hide_colorbar = TRUE
)
})
# Observe intro btn and start the intro
shiny::observeEvent(input$measuresIntro,
rintrojs::introjs(session, options = list(steps = measuresHelp))
)
# Knit shinyAce editor code
output$knitr <- shiny::renderUI({
# Create a Progress object
progress <- shiny::Progress$new()
# Make sure it closes when we exit this reactive, even if there's an error
on.exit(progress$close())
progress$set(message = "Building report...", value = 0)
input$eval
return(
shiny::isolate(
shiny::HTML(
knitr::knit2html(text = input$rmd, quiet = TRUE)
)
)
)
})
# Observe intro btn and start the intro
shiny::observeEvent(input$editorIntro,
rintrojs::introjs(session, options = list(steps = editorHelp))
)
# Trigger bookmarking
observeEvent(input$bookmark, {
session$doBookmark()
})
# Need to exclude the buttons from themselves being bookmarked
setBookmarkExclude("bookmark")
})
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.