server.R

library(shiny)
library(leaflet)
library(RColorBrewer)
library(scales)
library(lattice)
library(dplyr)
library(magrittr)
library(plotly)

# Leaflet bindings are a bit slow; for now we'll just sample to compensate
set.seed(100)
business_data <- business.df[sample.int(nrow(business.df), 60000),]
# By ordering by centile, we ensure that the (comparatively rare) SuperZIPs
# will be drawn last and thus be easier to see
business_data <- business_data[order(business.df$stars),]

cleantable <- business_data %>%
  select(
    City = city,
    State = state,
    Zipcode = zip_code,
    Stars = stars,
    Lat = latitude,
    Long = longitude
  )

shinyServer(function(input, output, session) {
  
  ## Interactive Map ###########################################
  
  # Create the map
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles(
        urlTemplate = "//{s}.tiles.mapbox.com/v3/jcheng.map-5ebohr46/{z}/{x}/{y}.png",
        attribution = 'Maps by <a href="http://www.mapbox.com/">Mapbox</a>'
      ) %>%
      setView(lng = -93.85, lat = 37.45, zoom = 4)
  })
  
  # A reactive expression that returns the set of zips that are
  # in bounds right now
  zipsInBounds <- reactive({
    if (is.null(input$map_bounds))
      return(business_data[FALSE,])
    bounds <- input$map_bounds
    latRng <- range(bounds$north, bounds$south)
    lngRng <- range(bounds$east, bounds$west)
    
    subset(business_data,
           latitude >= latRng[1] & latitude <= latRng[2] &
             longitude >= lngRng[1] & longitude <= lngRng[2])
  })
  
  # Filter the business, returning a data frame
  zipsIFiltered<- reactive({
    # Due to dplyr issue #318, we need temp variables for input values
    reviews <- input$reviews
    stars_input <- input$stars

    # Apply filters
    m <- subset(zipsInBounds(),
                review_count >= reviews &
                  stars >= stars_input)
    
    # Filter by category
    if (input$business_category != "All") {
      m <- m[which(grepl(input$business_category, m$categories)), ]
    }else
      m <- m
    
    # Filter open business
    if (input$open_checkbox==TRUE) {
      m <- m[which(m$open==TRUE), ]
    }else
      m <- m[which(m$open==FALSE), ]
    
  })
  
  output$histRanking <- renderPlotly({
    colorBy <- input$color
    colorData <- zipsIFiltered()[[colorBy]]
    
    if (nrow(zipsIFiltered()) == 0)
      return(NULL)
    
    pal<-colorPalette(colorData,colorBy)

    labelx <- paste(input$business_category, "business", input$color , "(visible business)", sep=" ")
    ax <- list(
      title = labelx,
      showticklabels = TRUE
    )
    
    ay <- list(
      title = input$size,
      showticklabels = TRUE
    )
    
    p<-plot_ly(zipsIFiltered(),type = "bar", x = zipsIFiltered()[[input$color]], y = zipsIFiltered()[[input$size]], 
           marker= list(color=pal(colorData)), size = zipsIFiltered()[[input$size]],showscale = FALSE)%>%
           layout(xaxis = ax, yaxis = ay)
    
  })
  
  output$scatterRanking <- renderPlotly({
    colorBy <- input$color
    colorData <- zipsIFiltered()[[colorBy]]
    
    if (nrow(zipsIFiltered()) == 0)
      return(NULL)
    
    pal<-colorPalette(colorData,colorBy)
    
    labelx <- paste(input$business_category, "business", input$color , "(visible business)", sep=" ")
    ax <- list(
      title = labelx,
      showticklabels = TRUE
    )
    
    ay <- list(
      title = input$size,
      showticklabels = TRUE
    )
    
    p<-plot_ly(zipsIFiltered(), x = zipsIFiltered()[[input$color]], y = zipsIFiltered()[[input$size]],
           mode = "markers", color= colorData,colors = "Spectral" , size = zipsIFiltered()[[input$size]],showscale = FALSE)%>%
    layout(xaxis = ax, yaxis = ay)
  })
  
  output$scatterRanking2 <- renderPlotly({
    if (nrow(zipsIFiltered()) == 0)
      return(NULL)
    
    # Get total review count for the states
    if(input$size=="Stars mark"){
      review_by_state <- aggregate( stars ~ state, data = zipsIFiltered(), FUN = sum)
      labelx <- paste(input$business_category, "business", input$color , "(visible business)", sep=" ")
      ax <- list(
        title = labelx,
        showticklabels = TRUE
      )
      
      ay <- list(
        title = input$size,
        showticklabels = TRUE
      )
      p<-plot_ly(review_by_state,type = "bar", x =state, y = stars,
                 size = stars)%>%
     layout(xaxis = ax, yaxis = ay)
   }
    else{
      review_by_state <- aggregate( review_count ~ state, data = zipsIFiltered(), FUN = sum)
      labelx <- paste(input$business_category, "business", input$color , "(visible business)", sep=" ")
      ax <- list(
        title = labelx,
        showticklabels = TRUE
      )
      
      ay <- list(
        title = input$size,
        showticklabels = TRUE
      )
      p<-plot_ly(review_by_state,type = "bar", x = state, y = review_count,
                 size = review_count)%>%
        layout(xaxis = ax, yaxis = ay)
    }
    
  })
  
  # This observer is responsible for maintaining the circles and legend,
  # according to the variables the user has chosen to map to color and size.
  observe({
    sizeBy <- input$size
    sizeRange <- input$size_scale
    colorBy <- input$color
    
    colorData <- zipsIFiltered()[[colorBy]]

    pal<-colorPalette(colorData,colorBy)
    radius <- zipsIFiltered()[[sizeBy]] * sizeRange 
    
    leafletProxy("map", data = zipsIFiltered()) %>%
      clearShapes() %>%
      addCircles(~longitude, ~latitude, radius=radius, layerId=~zip_code,
                 stroke=FALSE, fillOpacity=0.4, fillColor=pal(colorData)) %>%
      addLegend("bottomleft", pal=pal, values=colorData, title=colorBy,
                layerId="colorLegend")
  })
  
  
  # When map is clicked, show a popup with city info
  observe({
    leafletProxy("map") %>% clearPopups()
    event <- input$map_shape_click
    if (is.null(event))
      return()
    
    isolate({
      showZipcodePopup(event$id, event$lat, event$lng)
    })
  })
  
  # Show a popup at the given location
  showZipcodePopup <- function(zipcode, lat, lng) {
    selectedZip <- business_data[business_data$zip_code == zipcode,]
    content <- as.character(tagList(
      tags$h4(as.character(selectedZip$name)),
      tags$h5("Categories:", as.character(selectedZip$categories)),
      sprintf("Number of reviews: %s", as.integer(selectedZip$review_count)), tags$br(),
      sprintf("Stars score: %s", as.integer(selectedZip$stars))
    ))
    leafletProxy("map") %>% addPopups(lng, lat, content, layerId = zipcode)
  }
  
  # Calculate the color palette
  colorPalette <- function(colorData, colorBy) {
    if(colorBy=="stars" || colorBy=="review_count"){
      pal <- colorBin("Spectral", colorData, 4, pretty=TRUE,alpha = FALSE)
    }else{
      pal <- colorBin("Spectral", colorData, 4, pretty=TRUE,alpha = FALSE)
    }
    return (pal)
  }
  
  ## Data Explorer ###########################################
  
  observe({
    cities <- if (is.null(input$states)) character(0) else {
      filter(cleantable, State %in% input$states) %>%
        `$`('City') %>%
        unique() %>%
        sort()
    }
    stillSelected <- isolate(input$cities[input$cities %in% cities])
    updateSelectInput(session, "cities", choices = cities,
                      selected = stillSelected)
  })
  
  observe({
    zipcodes <- if (is.null(input$states)) character(0) else {
      cleantable %>%
        filter(State %in% input$states,
               is.null(input$cities) | City %in% input$cities) %>%
        `$`('Zipcode') %>%
        unique() %>%
        sort()
    }
    stillSelected <- isolate(input$zipcodes[input$zipcodes %in% zipcodes])
    updateSelectInput(session, "zipcodes", choices = zipcodes,
                      selected = stillSelected)
  })
  
  observe({
    if (is.null(input$goto))
      return()
    isolate({
      map <- leafletProxy("map")
      map %>% clearPopups()
      dist <- 0.5
      zip <- input$goto$zip
      lat <- input$goto$lat
      lng <- input$goto$lng
      showZipcodePopup(zip, lat, lng)
      map %>% fitBounds(lng - dist, lat - dist, lng + dist, lat + dist)
    })
  })
  
  output$ziptable <- DT::renderDataTable({
    df <- cleantable %>%
      filter(
        Stars >= input$minScore,
        Stars <= input$maxScore,
        is.null(input$states) | State %in% input$states,
        is.null(input$cities) | City %in% input$cities,
        is.null(input$zipcodes) | Zipcode %in% input$zipcodes
      ) %>%
      mutate(Action = paste('<a class="go-map" href="" data-lat="', Lat, '" data-long="', Long, '" data-zip="', Zipcode, '"><i class="fa fa-crosshairs"></i></a>', sep=""))
    action <- DT::dataTableAjax(session, df)
    
    DT::datatable(df, options = list(ajax = list(url = action)), escape = FALSE)
  })
})
yolanda93/yelp_challenge_ui documentation built on May 4, 2019, 5:31 p.m.