2

being a shiny newcomer myself, I struggle with adapting an example code to my particular dataset. My dataset is a "development subset" of the yelp dataset challenge.

My goal is to create a scatter plot of "stars" vs "number of reviews" of the restaurants in the current map section.

What I got: a map that shows markers for restaurants as well as a working filter to count the visible restaurants as debug message in the console.

My problem:

Listening on http://127.0.0.1:4587
num restaurants: 194 ## <- this number changes when changing the map section##
Warning: Error in [: object of type 'closure' is not subsettable
Stack trace (innermost first):
107: FUN
106: lapply
105: concat
104: lrep
103: latticeParseFormula
102: xyplot.formula
101: xyplot
100: print
 99: renderPlot [C:/SomePath/server.R#54]
 89: <reactive:plotObj>
 78: plotObj
 77: origRenderFunc
 76: output$scatterStarsReviewCount
  1: runApp

I read a lot of stack overflow posts which are dealing with that error message, but it seems that they all boil down to solutions similar to this or that. Unfortunately and to all I know so far, these hints are not helping to solve my problem.
I don't understand why the abovementioned example code is working and mine throws this error. They look very very similar.

Current Code:

ui.r

    library(shiny)
    library(leaflet)


    navbarPage(
      "Yelp",
      id = "nav",

      tabPanel(
        "Interactive map",
        div(
          class = "outer",

          tags$head(# Include our custom CSS
            includeCSS("styles.css"),
            includeScript("gomap.js")),

          # If not using custom CSS, set height of leafletOutput to a number instead of percent
          leafletOutput("map", width = "100%", height = "100%"),

          # Shiny versions prior to 0.11 should use class = "modal" instead.
          absolutePanel(
            id = "controls",
            class = "panel panel-default",
            fixed = TRUE,
            draggable = FALSE,
            top = 60,
            left = "auto",
            right = 20,
            bottom = "auto",
            width = 330,
            height = "auto",

            h3('ScatterPlot'),

            plotOutput("scatterStarsReviewCount", height = 250)
          )
        )
      )
    )

server.r

    library(leaflet)
    library(RColorBrewer)
    library(scales)
    library(lattice)
    library(dplyr)

    # Read pre-processed data
    bizrates <- read.table("bizrates.dat")

    function(input, output, session) {
      ## Interactive Map ###########################################

      # Create the map
      output$map <- renderLeaflet({

        Sbizrates = bizrates

        # generate map
        leaflet() %>%
          addTiles() %>%
          addTiles(urlTemplate = "http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png")  %>%
          mapOptions(zoomToLimits = "always") %>%

          addMarkers(
            lat = Sbizrates$biz_dat.latitude,
            lng = Sbizrates$biz_dat.longitude,
            clusterOptions = markerClusterOptions(),
            popup = Sbizrates$biz_dat.name
          )
      })


      # A reactive expression that returns the set of restaurants that are
      # in bounds right now
      restaurantsInBounds <- reactive({
        if (is.null(input$map_bounds))
          return(bizrates[FALSE,])
        bounds <- input$map_bounds
        latRng <- range(bounds$north, bounds$south)
        lngRng <- range(bounds$east, bounds$west)

        subset(bizrates,
               biz_dat.latitude >= latRng[1] & biz_dat.latitude <= latRng[2] &
                 biz_dat.longitude >= lngRng[1] & biz_dat.longitude <= lngRng[2])
      })

      output$scatterStarsReviewCount <- renderPlot({
        # If no restaurants are in view, don't plot
        if (nrow(restaurantsInBounds()) == 0)
         return(NULL)

        cat(file=stderr(), "num restaurants:", nrow(restaurantsInBounds()),"\n")

        print(xyplot(stars ~ reviewCount, data = restaurantsInBounds()), 
                     xlim = range(bizrates$biz_dat.stars), 
                     ylim = range(bizrates$biz_dat.review_count)
              )
      })
    }

Sample Data Set: bizrates.dat

"biz_dat.business_id" "biz_dat.name" "biz_dat.stars" "biz_dat.longitude" "biz_dat.latitude" "biz_dat.state" "biz_dat.attributes..Take.out." "biz_dat.attributes..Takes.Reservations." "biz_dat.attributes..Wi.Fi." "biz_dat.attributes.Caters" "biz_dat.review_count"
"5" "mVHrayjG3uZ_RLHkLj-AMg" "Emil's Lounge" 4.5 -79.8663507 40.408735 "PA" TRUE FALSE "no" TRUE 11
"6" "KayYbHCt-RkbGcPdGOThNg" "Alexion's Bar & Grill" 4 -80.067534 40.415517 "PA" TRUE FALSE "free" FALSE 15
"13" "b9WZJp5L1RZr4F1nxclOoQ" "Gab & Eat" 4.5 -80.0847998 40.3967441 "PA" TRUE FALSE "no" TRUE 38
"19" "rv7CY8G_XibTx82YhuqQRw" "Long John Silver's" 3.5 -80.0937037 40.3868915 "PA" TRUE FALSE "no" FALSE 3
"22" "wqu7ILomIOPSduRwoWp4AQ" "Denny's" 4 -80.073426 40.391255 "PA" TRUE FALSE "no" FALSE 7
"24" "P1fJb2WQ1mXoiudj8UE44w" "Papa J's" 3.5 -80.0854582 40.4082572 "PA" TRUE TRUE "no" TRUE 46
"26" "PK6aSizckHFWk8i0oxt5DA" "McDonald's" 2 -79.910032 40.412086 "PA" TRUE FALSE "free" FALSE 5
"30" "6ilJq_05xRgek_8qUp36-g" "Steak 'n Shake" 2 -79.9044562 40.413496 "PA" TRUE FALSE "no" FALSE 36
"32" "MKyk4F4HSzHF8v-4cYe3Ww" "Sing Sing" 3.5 -79.9151108 40.4094884 "PA" FALSE TRUE "no" FALSE 25
"37" "McikHxxEqZ2X0joaRNKlaw" "Rock Bottom" 3.5 -79.9151108 40.4094884 "PA" TRUE TRUE "no" FALSE 94

Note: In case someone wants to execute the code, the missing files (styles.css, gomap.js) can be found here.

Any help and ideas is appreciated!

Florian
  • 24,425
  • 4
  • 49
  • 80
arox
  • 23
  • 3

1 Answers1

0

To check where it went wrong, I made some print()statements in your code for making the xy-plot, for example print(colnames(restaurantsInBounds())). It turns out that the colnames are

[1] "biz_dat.latitude" "biz_dat.longitude" "biz_dat.name" "biz_dat.stars" "biz_dat.review_count"

But in the plotting function you refer to other columns:

print(xyplot(stars ~ reviewCount, data = restaurantsInBounds()),

You can fix it by modifying your function accordingly:

 output$scatterStarsReviewCount <- renderPlot({
    # If no restaurants are in view, don't plot
    if (nrow(restaurantsInBounds()) == 0)
      return(NULL)

    cat(file=stderr(), "num restaurants:", nrow(restaurantsInBounds()),"\n")

    print(colnames(restaurantsInBounds()))
    print(xyplot(biz_dat.stars ~ biz_dat.review_count, data = restaurantsInBounds()), 
          xlim = range(bizrates$biz_dat.stars), 
          ylim = range(bizrates$biz_dat.review_count)
    )
  })

result:

enter image description here

Hope this helps!

Florian
  • 24,425
  • 4
  • 49
  • 80