inst/shinyApp/server.R

library("magrittr")

shiny::shinyServer(function(input, output, session) {
  twitterdata <- shiny::reactive({
    #obtain the dataframe containing the top places for the requested city
    twitterfetch <-
      touristR::getTopNAttractions(as.character(input$choosecity), 15)
    #correcting the levels and format of the  fetched data
    twitterfetch <-
      data.frame(lapply(twitterfetch, function(x)
        unlist(x)))
    twitterfetch$lat <-
      as.numeric(levels(twitterfetch$lat))[twitterfetch$lat]
    twitterfetch$lng <-
      as.numeric(levels(twitterfetch$lng))[twitterfetch$lng]
    twitterfetch$name <-
      as.character(levels(twitterfetch$name))[twitterfetch$name]
    twitterfetch$hashtag <-
      as.character(levels(twitterfetch$hashtag))[twitterfetch$hashtag]
    #set the color depending on the sentiment level (value)
    #sentiment absolute setting colors
    twitterfetch <-
      twitterfetch %>% dplyr::mutate("sentimentcolorabsolute" =

                                       ifelse(
                                         sentimentAbsolute == 1,
                                         "green",
                                         ifelse(sentimentAbsolute == 0,
                                                "orange",
                                                "red")
                                       ))
    #sentiment relative setting colors
    twitterfetch <-
      twitterfetch %>% dplyr::mutate("sentimentcolorrelative" =

                                       ifelse(
                                         sentimentRelative == 1,
                                         "green",
                                         ifelse(sentimentRelative == 0,
                                                "orange",
                                                "red")
                                       ))

    twitterfetch <- twitterfetch %>% dplyr::mutate("radius" =
                                                     ifelse(popularity == 1,
                                                            40,
                                                            ifelse(
                                                              popularity == 0,
                                                                   25,
                                                                   10)))

    return(twitterfetch)

  })
  #obtaining the latitude and longitude of the requested city
  geotag <- shiny::reactive({
    geotag <- ggmap::geocode(location =
                               as.character(input$choosecity),
                             source = "dsk") %>% as.data.frame()
  })
  #rendering the map, depending on the checkbox selection (if checked
  #displays relative sentiment analysis/colors, if unchecked, the default
  #behaviour displays absolute sentiment analysis/colors)
  output$mymap <- leaflet::renderLeaflet({
    if (input$checkbox == FALSE) {
      plot_checkboxFALSE <-    leaflet::leaflet() %>%
        leaflet::addTiles()  %>%
        #add a minimap (on the bottom right)
        leaflet::addMiniMap(
          zoomLevelFixed = 5,
          height = 100,
          toggleDisplay = TRUE,
          minimized = FALSE
        ) %>%
        #add a button to locate the user(needed permission of the user and
        #opening the app in an external browser such as Google Chrome)
        leaflet::addEasyButton(
          leaflet::easyButton(
            icon = "fa-crosshairs",
            title = "Locate Me",
            onClick =
              htmlwidgets::JS("function(btn, map) {
                              map.locate({setView: true});
    }")
          )
        ) %>%
        #focus the geotag on the selected city as a whole
        leaflet::setView(lng = geotag()$lon[1]  ,
                         lat =  geotag()$lat[1] ,
                         zoom = 13) %>%
        #add markers in the map (colored based on the sentiment analysis)
        #(size of the circles based on the tweet counts)
        leaflet::addAwesomeMarkers(
          lng = twitterdata()$lng,
          lat = twitterdata()$lat,
          #add custom map marker icons
          icon = leaflet::awesomeIcons(
            icon = 'glyphicon glyphicon-map-marker',
            iconColor = 'black',
            library = 'glyphicon',
            markerColor = twitterdata()$sentimentcolorabsolute
          ),
          #displays a popup with the name of the place
          popup =  twitterdata()$name,
          #displays a label with the name of the place (on hover)
          label =  twitterdata()$name,
          #cluster results in the map for better readability
          clusterOptions = leaflet::markerClusterOptions(
            #specify custom style for the clustering circles (e.g. color)
            iconCreateFunction =
              htmlwidgets::JS(
                "function(cluster) {
                  return new L.DivIcon({
                    html: '<div style=\"background-color:rgba(77,77,77,0.5)\"><span>' +
                    cluster.getChildCount() + '</div><span>',
                    className: 'marker-cluster'
                  });
                }"
              )
          ),
          #id of the cluster elements
          clusterId = "Places"
        ) %>%

        #add circle markers
        #radius defined based on the popularity (count of tweets for that place)
        leaflet::addCircleMarkers(
          #longitude specification
          lng = twitterdata()$lng,
          #latitude specification
          lat = twitterdata()$lat,
          #color of the cicles (based on absolute sentiment)
          color =  twitterdata()$sentimentcolorabsolute,
          #radius of the circle, defined based on the tweets counts
          #provides a measure of popularitiy of a place
          radius =  twitterdata()$radius
        )
      plot_checkboxFALSE
      #if checkbox (Sentiment relative?) is checked
    } else if (input$checkbox == TRUE) {
      plot_checkboxTRUE <-    leaflet::leaflet() %>%
        #add a minimap (on the bottom right)
        leaflet::addTiles()  %>%  leaflet::addMiniMap(
          zoomLevelFixed = 5,
          height = 100,
          toggleDisplay = TRUE,
          minimized = FALSE
        ) %>%
        #add a button to locate the user(needed permission of the user and
        #opening the app in an external browser such as Google Chrome)
        leaflet::addEasyButton(
          leaflet::easyButton(
            icon = "fa-crosshairs",
            title = "Locate Me",
            onClick = htmlwidgets::JS("function(btn, map) {
                                         map.locate({setView: true});
                                        }"
                                      )
          )
        ) %>%
        #focus the geotag on the selected city as a whole
        leaflet::setView(lng = geotag()$lon[1]  ,
                         lat =  geotag()$lat[1] ,
                         zoom = 13) %>%
        #add markers in the map (colored based on the sentiment analysis)
        #(size of the circles based on the tweet counts)
        leaflet::addAwesomeMarkers(
          lng = twitterdata()$lng,
          lat = twitterdata()$lat,
          #add custom map marker icons
          icon = leaflet::awesomeIcons(
            icon = 'glyphicon glyphicon-map-marker',
            iconColor = 'black',
            library = 'glyphicon',
            markerColor = twitterdata()$sentimentcolorrelative
          ),
          #displays a popup with the name of the place
          popup = twitterdata()$name,
          #displays a label with the name of the place (on hover)
          label = twitterdata()$name,
          #cluster results in the map for better readability
          clusterOptions = leaflet::markerClusterOptions(
            #specify custom style for the clustering circles (e.g. color)
            iconCreateFunction =
              htmlwidgets::JS(
                "function(cluster) {
                  return new L.DivIcon({
                    html: '<div style=\"background-color:rgba(77,77,77,0.5)\"><span>' +
                    cluster.getChildCount() +
                    '</div><span>',
                    className: 'marker-cluster'
                  });
                 }"
              )

          ),
          #id of the cluster elements
          clusterId = "Places"
        ) %>%
        #add circle markers
        #radius defined based on the popularity (count of tweets for that place)
        leaflet::addCircleMarkers(
          #longitude specification
          lng = twitterdata()$lng,
          #latitude specification
          lat = twitterdata()$lat,
          #color of the cicles (based on absolute sentiment)
          color =  twitterdata()$sentimentcolorrelative,
          #radius of the circle, defined based on the tweets counts
          #provides a measure of popularitiy of a place
          radius =  twitterdata()$radius
        )

      plot_checkboxTRUE

    }

  })

  #Authenticate to twitter
  authentication <-
    vosonSML::Authenticate(
      "twitter",
      apiKey = 'ugjqg8RGNvuTAL1fEiNtw',
      apiSecret = '4WjuEbP6QLUN2DwDzyTwmdMES6fgnOsS65fWxpT8I',
      accessToken =  '76887198-JA3xCVO1vvQMqMDiIobWKKGQxYKSB0CV2lI2PZ7GL',
      accessTokenSecret = 'IvzlVOC8KkIaMR5s5K4u2IXbxKQv7EcUSvy2bnaru8gKz'
    )

  #query Twitter for the selected city (in #) to obtain
  #the dataframe containing the requested city tweets
  twitter_comment_city <- shiny::reactive({
    #query Twitter for the selected city and save results
    #in a dataframe
    twitter_comment_city <- vosonSML::Collect(
      credential = authentication,
      #paste the city as e.g. #london
      searchTerm = paste("#",  input$choosecity , sep = ""),
      #300 tweets requested for the input city
      numTweets = 300,
      writeToFile = FALSE,
      #obtain only tweets in English
      language = "en",
      verbose = TRUE
    )

    #rename column value to tweet (tweet texts obtained)
    twitter_comment_city <-
      twitter_comment_city$text %>% tibble::as.tibble() %>%
      dplyr::rename("tweet" = value)

  })

  #rendering the table of tweets
  output$city_twitterdatatable <- DT::renderDataTable({
    DT::datatable(
      twitter_comment_city(),
      rownames = FALSE,
      colnames = "Sample of tweets",
      autoHideNavigation = TRUE,
      #adding aesthetic to highlight a selected cell
      class = 'cell-border stripe',
      options = list(pageLength = 10,  scrollX =
                       '1000px'),
      #add a subtitle
      caption = tags$em(paste(
        "Twitter data results for city:",
        #paste name of the city in the format e.g. London
        #first letter capitalized and the rest in small case letters
        paste(
          toupper(substr(input$choosecity, 1, 1)),
          substr(input$choosecity, 2, nchar(input$choosecity)) ,
          sep = ""
        ),

        sep = " "
      ))

    )

  })

  output$place_query <- shiny::renderUI({
    #add a select input (among the available places found in the map)
    shiny::selectInput(
      inputId = "place_query_choice",
      label = "Choose a place!",
      #provide a vector with the names of all the available
      #places
      choices =  dput(as.character(twitterdata()$name)),
      selected = as.character(twitterdata()$name)[1],
      multiple = FALSE,
      selectize = TRUE

    )

  })
  #sets a reactive compoent (name of the selected place from
  #previously)
  input_search_twitterplace <- shiny::reactive({
    input_search_twitterplace <- input$place_query_choice

  })

  twitter_comment_place <- shiny::reactive({
    #query Twitter for the selected city (in #) to obtain
    #the dataframe containing the requested city tweets
    twitter_comment_place <-    vosonSML::Collect(
      credential = authentication,
      #paste the city as e.g. #london
      searchTerm = paste("#", input_search_twitterplace() , sep = ""),
      #300 tweets requested for the input city
      numTweets = 300,
      writeToFile = FALSE,
      #obtain only tweets in English
      language = "en",
      verbose = TRUE
    )

    #obtain the tweets (texts) and set them as tibbl with column name = tweet
    twitter_comment_place <-
      twitter_comment_place$text %>% tibble::as.tibble() %>%
      dplyr::rename("tweet" = value)

  })
  #render the results (tweets) in a reactive datatable
  output$place_twitterdatatable <- DT::renderDataTable({
    DT::datatable(
      twitter_comment_place(),
      rownames = FALSE,
      colnames = "Sample of tweets",
      autoHideNavigation = TRUE,
      #adding aesthetic to highlight a selected cell
      class = 'cell-border stripe',
      options = list(pageLength = 10,  scrollX = '1000px'),
      caption = tags$em(paste(
        "Twitter data results for place:",
        #paste name of the city in the format e.g. London
        #first letter capitalized and the rest in small case letters
        paste(
          toupper(substr(input$place_query_choice, 1, 1)),
          substr(
            input$place_query_choice,
            2,
            nchar(input$place_query_choice)
          ) ,
          sep = ""
        ),

        sep = " "
      ))

    )

  })

})
AyrtonRua/group1_project documentation built on May 14, 2019, 5:14 a.m.