Complete code R Shiny app example lab 6


Packages used:

library(shiny)
library(tidyverse)
library(MASS)
library(ISLR)

Code for UI.R

# Define UI for application that draws a histogram
shinyUI(fluidPage(

    # Application title
    titlePanel("Statistics in the Sky with Diamonds"),
    
    # Description
    p("A Shiny application, predicting the Carat of different Cuts of Diamonds, by their Price."),
    
    

    # Sidebar with a slider input for number of bins
    sidebarLayout(
        sidebarPanel(
        
            sliderInput("priceInput", "Price", 0, 20000, c(100, 10000)),
            sliderInput("caratInput", "Carat", 0, 5, c(0, 5), step = 0.1),
            checkboxGroupInput("cutInput", "Diamond Cut",
                     choices = c("Fair", "Good", "Very Good", "Premium", "Ideal"),
                     selected = c("Fair", "Good", "Very Good", "Premium", "Ideal")),
            selectInput("colInput", "Colour Choice", 
                     choices = c("Pastel1", "Paired", "Spectral", "RdBu", "PuOr"),
                     selected = "Spectral"),
            checkboxInput("regInput", "Linear regression", value = FALSE, width = NULL),
            checkboxInput("sqInput", "Square regression", value = FALSE, width = NULL),
            checkboxInput("cubInput", "Cubic regression", value = FALSE, width = NULL)
            ),

        # Show a plot of the generated distribution
        mainPanel(
            
            # Sub-Heading
            h4("Graphical Output"),
            
            # Main Graphical Output
            plotOutput("diaPlot"),
            
            # Sub-Heading
            h4("Statistical Analysis"),
            
            # Statistical Analysis Outcome
            tableOutput("modelres"),
            
            # Text Commentary 
            textOutput("statout")
        )
    )
))

Code for Server.R

# Define server logic required to draw a histogram
shinyServer(function(input, output) {
    
    # Plotting Example
    output$diaPlot <- renderPlot({

        filtered <- 
            diamonds %>%
            filter(price >= input$priceInput[1],
                   price <= input$priceInput[2],
                   carat >= input$caratInput[1],
                   carat <= input$caratInput[2],
                   cut == input$cutInput
            )
        model.lin <- lm(carat ~ price, data = filtered)
        model.sq <- lm(carat ~ price + I(price^2), data = filtered)
        model.cub <- lm(carat ~ price + I(price^2) + I(price^3), data = filtered)
        
        x_pred <- seq(min(filtered$price), max(filtered$price), length.out = 500)
        y_pred.lin <- predict(model.lin, newdata = tibble(price = x_pred))
        y_pred.sq <- predict(model.sq, newdata = tibble(price = x_pred))
        y_pred.cub <- predict(model.cub, newdata = tibble(price = x_pred))
        
        ggplot(data = filtered, 
               mapping = aes(x = price, y = carat, colour = cut)) + 
            geom_point() +
            geom_line(data = tibble(price = x_pred, carat = y_pred.lin), size = input$regInput, col = "blue") +
            geom_line(data = tibble(price = x_pred, carat = y_pred.sq), size = input$sqInput, col = "red") +
            geom_line(data = tibble(price = x_pred, carat = y_pred.cub), size = input$cubInput, col = "green") +
            scale_color_brewer(palette = input$colInput) + 
            theme_minimal()
        
        
        
    })
    
    # Model Table output
    output$modelres <- renderTable({
        filtered <- 
            diamonds %>%
            filter(price >= input$priceInput[1],
                   price <= input$priceInput[2],
                   carat >= input$caratInput[1],
                   carat <= input$caratInput[2],
                   cut == input$cutInput
            )
        model.lin <- lm(carat ~ price, data = filtered)
        model.sq <- lm(carat ~ price + I(price^2), data = filtered)
        model.cub <- lm(carat ~ price + I(price^2) + I(price^3), data = filtered)
        
        model.lin.sum <- summary(model.lin)
        model.sq.sum <- summary(model.sq)
        model.cub.sum <- summary(model.cub)
        
        tablemodelres <- matrix(c("Linear regression", "Square regression", "Cubic regression",
                                  round(model.lin.sum$r.squared, 3), round(model.sq.sum$r.squared, 3), 
                                  round(model.cub.sum$r.squared, 3), round(model.lin.sum$adj.r.squared, 3), 
                                  round(model.sq.sum$adj.r.squared, 3), round(model.cub.sum$adj.r.squared, 3),
                                  model.lin.sum$df[2], model.sq.sum$df[2], model.cub.sum$df[2]), ncol = 4)
        colnames(tablemodelres) <- c(" ", "R-squared", "Adj R-squared", "df")
        
        
        tablemodelres
        })
    
    # Model Statistical Output (Text)
    output$statout <- renderText({
        
        filtered <- 
            diamonds %>%
            filter(price >= input$priceInput[1],
                   price <= input$priceInput[2],
                   carat >= input$caratInput[1],
                   carat <= input$caratInput[2],
                   cut == input$cutInput
            )
        model.lin <- lm(carat ~ price, data = filtered)
        model.sq <- lm(carat ~ price + I(price^2), data = filtered)
        model.cub <- lm(carat ~ price + I(price^2) + I(price^3), data = filtered)
        
        model.lin.sum <- summary(model.lin)
        model.sq.sum <- summary(model.sq)
        model.cub.sum <- summary(model.cub)
        
        model.lin.sum[["name"]] <- "Linear regression"
        model.sq.sum[["name"]] <- "Square regression"
        model.cub.sum[["name"]] <- "Cubic regression"
        
        # Best fitting model, with R-squared
        if((model.lin.sum$adj.r.squared > model.sq.sum$adj.r.squared) & (model.lin.sum$adj.r.squared > model.cub.sum$adj.r.squared)){
                model.text.out <- model.lin.sum
        } else if((model.sq.sum$adj.r.squared > model.lin.sum$adj.r.squared) & (model.sq.sum$adj.r.squared > model.cub.sum$adj.r.squared)){
                model.text.out <- model.sq.sum
        } else if ((model.cub.sum$adj.r.squared > model.lin.sum$adj.r.squared ) & (model.cub.sum$adj.r.squared > model.sq.sum$adj.r.squared)){
                model.text.out <- model.cub.sum
        }
        
        paste0("The regression analysis which most accounts for the relationship is: ", model.text.out$name, ". ", 
               "With an Adjusted R-squared of: ", round(model.text.out$adj.r.squared, 3), ", F(",
               model.text.out$fstatistic[2], ", ", model.text.out$fstatistic[3], ") = ", round(model.text.out$fstatistic[1],3), ".")
    })

        

})