Why not use a Shiny app? You can use the code below as starting point.
library(shiny)
library(dbscan)
library(ggplot2)
library(shinycssloaders) # Loading/busy animations
ui <- fluidPage(
titlePanel("Input", windowTitle = "DBSCAN"),
## Sidebar with input and output definitions
sidebarLayout(
position = c("left", "right"),
fluid = TRUE,
## Sidebar panel for inputs
sidebarPanel(
width = 3,
h4("Data file"),
## Input: Select a csv file
fileInput("datafile", "Select data file (in csv format)",
multiple = FALSE,
accept = c("text/csv",
"text/comma-separated-values,text/plain",
".csv")),
## Checkbox if file has header
checkboxInput("header", "File has header", TRUE),
## Select separator
radioButtons("sep", "Separator",
choices = c(Comma = ",",
Semicolon = ";",
Tab = "\t"),
selected = "\t"),
## Select quotes
radioButtons("quote", "Quote",
choices = c(None = "",
"Double Quote" = '"',
"Single Quote" = "'"),
selected = '"'),
tags$hr(style="border-top: 1px solid #000000;"),
h4("Plot"),
## Select variables to display
uiOutput("plotVariables"),
tags$hr(style="border-top: 1px solid #000000;"),
h4("DBSCAN"),
## Select variables to use for clustering
uiOutput("clusterVariables"),
## DBSCAN input parameters
numericInput('eps', 'Size of the epsilon neighbourhood (eps)', NULL),
numericInput('minPts', 'Number of minimum points in the eps region (minPts)', 5, min = 1),
actionButton("clusterButton", "Cluster away!")
),
mainPanel(
width = 9,
fluidRow(
column(9,
fluidRow(
h3('Plot'),
withSpinner(
plotOutput('plot', height = 600, width = '100%')
)
)
)
)
)
)
)
server <- function(input, output, session) {
rv <- reactiveValues(data = NULL, clusters = NULL)
## Read uploaded data file
observeEvent(input$datafile, {
if (is.null(input$datafile)) return(NULL)
req(input$datafile) ## Proceed only if file selected
rv$data <- read.csv(input$datafile$datapath,
header = input$header,
sep = input$sep,
quote = input$quote,
stringsAsFactors = FALSE)
## Remove non-numeric columns to be safe for clustering
rv$data <- rv$data[,sapply(rv$data, is.numeric)]
})
## Dynamically generate UI input to select variables once data is uploaded and read
## Do once to select variables to plot and once to select variables to use for clustering
output$plotVariables <- renderUI({
selectizeInput(inputId = "plotVar",
label = "Variables to plot",
multiple = TRUE,
choices = names(rv$data),
options = list(maxItems = 2))
})
output$clusterVariables <- renderUI({
selectizeInput(inputId = "clusterVar",
label = "Variables to use for clustering",
multiple = TRUE,
choices = names(rv$data))
})
## Do clustering once button is pressed
observeEvent(input$clusterButton, {
if(!is.na(input$eps && length(input$clusterVar)>0)) {
dbr <- dbscan(as.matrix(rv$data[, input$clusterVar]), input$eps, input$minPts)
rv$clusters <- dbr$cluster
}
})
## Plot
output$plot <- renderPlot({
selectedCols <- input$plotVar
if (length(selectedCols) == 2) {
p <- ggplot(data = rv$data, aes_string(x = selectedCols[1], y = selectedCols[2])) +
labs(x = eval(selectedCols[1]), y = eval(selectedCols[2]))
if(!is.null(rv$clusters)) { # We have clusters
p <- p + geom_point(aes(colour = factor(rv$clusters))) +
scale_colour_brewer('Clusters', palette = 'Set1')
} else { # No clustering
p <- p + geom_point(color = 'darkblue')
}
p <- p + coord_cartesian(expand = TRUE)
plot(p)
}
})
}
## Run the application
shinyApp(ui = ui, server = server)
What is the sample data to run this GUI? should there be a rule? I managed to run tis GUI but when entering data can't run it. Thank you very much.