diff --git a/server.R b/server.R index 7598b0c..273aaa6 100644 --- a/server.R +++ b/server.R @@ -23,12 +23,16 @@ DF_EvCode <- read_csv("DF_EvCodeData.csv") # Data manipulation and saving to the DF_TEMP DF_TEMP <- DF_Data %>% + # arrange by date + arrange(StartDateTime) %>% # join to decode equipment serial number inner_join(DF_Equipm, by = "IDEquipment") %>% + # select only column needed + select(StartDateTime, Name, EventCode, TimeTotal) %>% # join to decode Event Code meaning inner_join(DF_EvCode, by = "EventCode") %>% # select only column needed - select(StartDateTime, Name, TimeTotal, EventText) + select(StartDateTime, Name, EventCode, TimeTotal, EventText) # ================================= shinyServer(function(input, output, session) { @@ -53,8 +57,8 @@ shinyServer(function(input, output, session) { DF_TEMP %>% # filters for categories filter(EventText == input$selInput) %>% - # group by - group_by(Name) %>% + # group by + group_by(Name) %>% # filters X date filter(StartDateTime > StartDate(), StartDateTime < EndDate()) }) @@ -63,121 +67,113 @@ shinyServer(function(input, output, session) { # Prepare data for clustering and do clustering with if/else statement... DF_SUM_ALL <- reactive({ - # Data manipulation and saving to the DF_Data reactive value - DF_KM <- DF_TEMP %>% #filter(EventText == "Step 2 SubStep 6") - # filters for category - filter(EventText == input$Step) - - # make intermediate dataframe - KM1 <- DF_KM %>% - select(Name, TimeTotal) %>% - mutate(Name = revalue(Name, c("Machine #1" = "1", "Machine #2" = "2", "Machine #3" = "3", "Machine #4" = "4"))) %>% - mutate(Name = as.numeric(Name)) - - # perform different modelling depending on the user choice... - if(!input$scaled) { - KM <- KM1 %>% - kmeans(centers = Classes(), nstart = 20) - } else { - KM <- KM1 %>% - scale() %>% - as.data.frame() %>% - kmeans(centers = Classes(), nstart = 20) - } - - # saving clustering result to the new data frame - vector <- as.data.frame.vector(KM$cluster) - names(vector) <- "Clust" - - DF_SUM_ALL <- DF_KM %>% - select(StartDateTime, TimeTotal, Name) %>% - # join clustering result - bind_cols(vector) %>% - mutate(Clust = as.factor(Clust)) - - + # Data manipulation and saving to the DF_Data reactive value + DF_KM <- DF_TEMP %>% #filter(EventText == "Step 2 SubStep 6") + # filters for category + filter(EventText == input$Step) + + # make intermediate dataframe + KM1 <- DF_KM %>% + select(Name, TimeTotal) %>% + mutate(Name = revalue(Name, c("Machine #1" = "1", "Machine #2" = "2", "Machine #3" = "3", "Machine #4" = "4"))) %>% + mutate(Name = as.numeric(Name)) + + # perform different modelling depending on the user choice... + if(!input$scaled) { + KM <- KM1 %>% + kmeans(centers = Classes(), nstart = 20) + } else { + KM <- KM1 %>% + scale() %>% + as.data.frame() %>% + kmeans(centers = Classes(), nstart = 20) + } + + # saving clustering result to the new data frame + vector <- as.data.frame.vector(KM$cluster) + names(vector) <- "Clust" + + DF_SUM_ALL <- DF_KM %>% + select(StartDateTime, TimeTotal, Name) %>% + # join clustering result + bind_cols(vector) %>% + mutate(Clust = as.factor(Clust)) + + }) + # ================================= -# FUNCTIONS +# OUTPUTS # ================================= - # Function to draw main plot, using condition of input$point to add points to the graph - mainPlot <- function(){ - if(input$points){ - DF_SUM() %>% - ggplot(aes(x = StartDateTime, y = TimeTotal, col = EventText)) + - geom_smooth(alpha = 0.5, se = StatErr(), formula = y ~ poly(x, 2)) + - geom_point(alpha = 0.4) + - facet_wrap(~Name) + ylab("Duration of Step, seconds") + - ggtitle(paste("Overview of Steps ", "from: ", - StartDate(), " to: ", EndDate(), sep = "")) - - } else { - DF_SUM() %>% - ggplot(aes(x = StartDateTime, y = TimeTotal, col = EventText)) + - geom_smooth(alpha = 0.5, se = StatErr(), formula = y ~ poly(x, 2)) + - facet_wrap(~Name) + ylab("Duration of Step, seconds") + - ggtitle(paste("Overview of Steps ", "from: ", - StartDate(), " to: ", EndDate(), sep = "")) - - } - } + ### Render function to create a main plot: + output$Plot <- renderPlot({ + # generate object for the plot using DF_SUM + DF_SUM() %>% + ggplot(aes(x = StartDateTime, y = TimeTotal, col = EventText)) + + geom_smooth(alpha = 0.5, se = StatErr()) + + facet_wrap(~Name) + ylab("Duration of Step, seconds") + + ggtitle(paste("Overview of Steps ", "from: ", + StartDate(), " to: ", EndDate(), sep = "")) + }) + + # ================================= - # Function to draw Box plot - boxPlot <- function(){ + ### Render function to create a main plot: + output$Plot1 <- renderPlot({ + # generate object for the plot using DF_SUM + DF_SUM() %>% + ggplot(aes(x = StartDateTime, y = TimeTotal, col = EventText)) + geom_point()+ + geom_smooth(alpha = 0.5, se = StatErr()) + + facet_wrap(~Name) + + ylab("Duration of Step, seconds") + + ggtitle(paste("Overview of Steps ", "from: ", + StartDate(), " to: ", EndDate(), sep = "")) + }) + + # ================================= + + ### Render function to create another plot: + output$Plot2 <- renderPlot({ + # generate object for the plot using DF_SUM DF_SUM() %>% ggplot(aes(x = StartDateTime, y = TimeTotal, col = EventText)) + geom_boxplot() + - facet_grid(~Name) + - ylab("Duration of Step, seconds") + - theme(legend.direction = "horizontal", legend.position = "bottom")+ - ggtitle(label = paste("Box Plot from all data. From: ", StartDate(), " To: ", EndDate(), sep = ""), - subtitle = "Box plots can help to indicate average values and outliers") - - } - # Function to draw deviation plot + facet_wrap(Name ~ EventText) + + ggtitle(paste("Overview of Steps ", "from: ", + StartDate(), " to: ", EndDate(), sep = "")) + }) + + + # ================================= + ### function that creates a plot deviationPlot <- function(){ - + # generate object for the plot using DF_SUM DF_SUM_ALL() %>% filter(StartDateTime > StartDate(), StartDateTime < EndDate()) %>% - ggplot(aes(x = StartDateTime, y = TimeTotal, col = Clust)) + geom_point() + facet_wrap(~Name)+ - ylab("Duration of Step, seconds") + - theme(legend.direction = "horizontal", legend.position = "bottom")+ - ggtitle(label = paste("Anomaly Detection of the Step Duration. From: ", StartDate(), " To: ", EndDate(), sep = ""), - subtitle = "Different colors may highlight potential anomaly") - + ggplot(aes(x = StartDateTime, y = TimeTotal, col = Clust)) + geom_point() + facet_wrap(~Name) + + + ggtitle(paste("Anomaly Detection of the Step Duration", "from: ", + StartDate(), " to: ", EndDate(), ". Different colour indicates potential anomaly", sep = "")) } -# ================================= -# OUTPUTS -# ================================= - - ### Render function to create a main plot: - output$Plot <- renderPlot({ - ggsave("plot.png", plot = mainPlot(), device = "png") - mainPlot() }, height = "auto", width = 650) - - # ================================= - - ### Render function to create Box Plot: - output$Plot2 <- renderPlot({ - ggsave("plot.png", plot = boxPlot(), device = "png") - boxPlot() }, height = "auto", width = 650) # ================================= - ### Render function to create plot Anomaly: - output$Plot3 <- renderPlot({ + ### Render function to create another plot: + output$Plot3 <- renderPlot({ ggsave("plot.png", plot = deviationPlot(), device = "png") - deviationPlot() }, height = "auto", width = 650) + deviationPlot() + }) - # ================================= - ### download plot: + # ================================= + ### Download plot : output$downloadPlot <- downloadHandler( - filename = function(){ "plot.png"}, - content = function(file){ + filename = function(){"plot.png"}, + content = function(file){ file.copy("plot.png", file, overwrite = TRUE) - } - ) + } + ) + }) \ No newline at end of file diff --git a/ui.R b/ui.R index 8f66d04..119c54a 100644 --- a/ui.R +++ b/ui.R @@ -9,7 +9,6 @@ # ---------------------------- library(shiny) -library(shinydashboard) library(DT) # Define steps choices for selectInput function (it is containing steps the user can filter) @@ -25,42 +24,54 @@ stepsChoices <- c("Step 1 SubStep 1", "Step 2 SubStep 6", "Step 2 SubStep 7") -# -dashboardPage( - dashboardHeader(title = "Preparation Steps Duration Overview"), - dashboardSidebar( - # Elements on the Sidebar of the App - img(height = 100, width = 230, src = "logo.png"), - dateInput(inputId = "DateStart", label = "Insert Start Date", value = "2017-01-01"), - dateInput(inputId = "DateEnd", label = "Insert End Date", value = "2017-09-01"), - helpText("Note: Set Desired dates of interest", - "and select plots below to visualize", - "specific step of interest."), - selectInput(inputId = "selInput",label = "Add Machine Steps to Analysis", choices = stepsChoices, - selected = stepsChoices[1], multiple = TRUE, selectize = TRUE, width = '100%', size = NULL), - checkboxInput(inputId = "cboxSE", label = "Add Stat Error?", value = FALSE, width = NULL), - checkboxInput(inputId = "points", label = "Add Points?"), - div(style="display:inline-block;width:65%;text-align: right;",downloadButton(outputId = "downloadPlot",label = "Download Plot")) - - ), - dashboardBody( - - mainPanel( - - # Elements of the Dashboard: header and tabset panel - headerPanel("Visualization of steps duration"), - tabsetPanel( - # Default chart visualizing the overall performance of the systems - tabPanel("Plot - Overview", plotOutput(outputId = "Plot")), - # Box plot helping to perform comparison - tabPanel("Plot - Box Plot", plotOutput(outputId = "Plot2")), - tabPanel("Plot - Anomaly", column(4, selectInput(inputId = "Step",label = "ChooseStep", choices = stepsChoices, - selected = stepsChoices[1], multiple = FALSE, selectize = TRUE, size = NULL)), - column(4, numericInput(inputId = "numClasses", label = "Select Number of Classes", - value = 2, min = 1, max = 4, step = 1)), - column(4, checkboxInput(inputId = "scaled", label = "Scale Data?", value = FALSE)), hr(), - plotOutput(outputId = "Plot3")) - ) - ) - ) -) +shinyUI(fluidPage(theme = "bootstrap.css", + + # Page Row 1 == Information Pane == + # Adding Logo [optional] + fluidRow(column(2, img(height = 50, width = 106, src = "logo.JPG")), + column(9, + # Application title + titlePanel("Preparation Steps Duration Overview"))), + + # Adding a horizontal line + hr(), + + # Page Row 2 == User Inputs == + + fluidRow(column(2, dateInput(inputId = "DateStart", label = "Insert Start Date", value = "2017-01-01")), + column(2, dateInput(inputId = "DateEnd", label = "Insert End Date")), + column(1, checkboxInput(inputId = "cboxSE", label = "Add Stat Error?", value = FALSE, width = NULL)), + column(3, helpText("Note: while the data view will show only", + "the specified number of observations, the", + "summary will be based on the full dataset."))), + fluidRow(column(8, selectInput(inputId = "selInput",label = "Add Machine Steps to Analysis", choices = stepsChoices, + selected = stepsChoices[1], multiple = TRUE, + selectize = TRUE, width = '100%', size = NULL))), + + # Adding a horizontal line + hr(), + + # Page Row 3 == Plot or other Outputs == + fluidRow(column(12, + # Show a plot + mainPanel( + tabsetPanel( + tabPanel("Plot - Smoothed", plotOutput("Plot")), + tabPanel("Plot - Points", plotOutput("Plot1")), + tabPanel("Plot - Box Plot", plotOutput("Plot2")), + tabPanel("Deviation Auto Detection", "Select machine step and choose the dates of interest", + hr(), + column(4, selectInput(inputId = "Step",label = "ChooseStep", choices = stepsChoices, + selected = stepsChoices[1], multiple = FALSE, + selectize = TRUE, size = NULL)), + column(3, checkboxInput(inputId = "scaled", label = "Scale Data?", value = FALSE), + downloadButton(outputId = "downloadPlot", label = "Download Plot")), + column(4, numericInput(inputId = "numClasses", label = "Select Number of Classes", + value = 2, min = 1, max = 4, step = 1)), hr(), + plotOutput(outputId = "Plot3")) + ) + + ) + )) +)) +