I am trying to make a shiny app where I can select a location on the map and display a gauge chart for each corresponding location. I have been able to make the app reactive but the googlevis gauge display appears on the browser instead of in the app. In the app I get the error $ operator is invalid for atomic vectors. I tried converting the data into a dataframe but I am still getting this error. the code is as follows
library(shiny)
library(leaflet)
library(shinydashboard)
library(dplyr)
library(googleVis)
#Making the Dataframe
locations<-c("A","B","C")
x<-c(36.05617,36.05626,36.05634)
y<-c(-2.1007,-2.05553,-2.01035)
yield<-c(5.86,3.06,1.07)
df<-data.frame(locations,x,y,yield)
################## Defining UI for application ############################
ui <- shinyUI(dashboardPage(title = "Yield Lookup",
dashboardHeader(title = "Crop Yield (Tonnes per Hectare)",titleWidth = 350),
dashboardSidebar(
sidebarMenu(
menuItem("Map Dashboard", tabName = "datavis", icon = icon("map", verify_fa = FALSE)),
menuItem("Select by Location Name", icon = icon("leaf"),
selectizeInput("locations", "Click on Location", choices = levels(factor(df$locations)))
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "datavis",
h4("Map and Plot"),
fluidRow(box(width= 8, leafletOutput("map", height = 800)),
box("Gauge for crop yield by area",width = 4, htmlOutput("myplot")))
)
)
)
)
)
################## Defining Server for application ############################
server<- shinyServer(function(input,output, session){
## Sub data
lo<-reactive({
})
locat_data <- reactive({
df[df$locations %in% input$locations,]
})
output[["myplot"]] <- renderGvis({
newdf<-locat_data()%>%select(locations, yield)
newdf<-as.data.frame(newdf)
Gauge <- gvisGauge(as.data.frame(newdf),
options=list(min=0, max=6, greenFrom=4,
greenTo=6, yellowFrom=2, yellowTo=4,
redFrom=0, redTo=2, width=400, height=300))
plot(Gauge)
})
output$map <- renderLeaflet({
leaflet(df) %>%
addTiles() %>%
addCircleMarkers(lng = ~x, lat = ~y, layerId = ~locations, color = "blue", radius = 3) %>%
addCircles(lng = ~x, lat = ~y, weight = 1,
radius = 1, label = ~locations
)
})
observeEvent(input$locations,{
updateSelectInput(session, "locations", "Click on Locations",
choices = levels(factor(df$locations)),
selected = c(input$locations))
})
observeEvent(input$map_marker_click, {
click <- input$map_marker_click
location <- df[which(df$y == click$lat & df$x == click$lng), ]$locations
updateSelectInput(session, "locations", "Click on Location",
choices = levels(factor(df$locations)),
selected = c(input$locations, location))
})
})
shinyApp(ui=ui, server = server)
I am not sure where I am going wrong. Please help.
CodePudding user response:
You were very close.
Just drop the plot()
and leave Gauge
in the server section. (Alternatively drop the Gauge <-
and Gauge
on the next line and just leave gvisGauge()
)
library(shiny)
library(leaflet)
library(shinydashboard)
library(dplyr)
library(googleVis)
#Making the Dataframe
locations<-c("A","B","C")
x<-c(36.05617,36.05626,36.05634)
y<-c(-2.1007,-2.05553,-2.01035)
yield<-c(5.86,3.06,1.07)
df<-data.frame(locations,x,y,yield)
################## Defining UI for application ############################
ui <- shinyUI(dashboardPage(title = "Yield Lookup",
dashboardHeader(title = "Crop Yield (Tonnes per Hectare)",titleWidth = 350),
dashboardSidebar(
sidebarMenu(
menuItem("Map Dashboard", tabName = "datavis", icon = icon("map", verify_fa = FALSE)),
menuItem("Select by Location Name", icon = icon("leaf"),
selectizeInput("locations", "Click on Location", choices = levels(factor(df$locations)))
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "datavis",
h4("Map and Plot"),
fluidRow(box(width= 8, leafletOutput("map", height = 800)),
box("Gauge for crop yield by area",width = 4, htmlOutput("myplot")))
)
)
)
)
)
################## Defining Server for application ############################
server<- shinyServer(function(input,output, session){
## Sub data
lo<-reactive({
})
locat_data <- reactive({
df[df$locations %in% input$locations,]
})
output[["myplot"]] <- renderGvis({
newdf<-locat_data()%>%select(locations, yield)
newdf<-as.data.frame(newdf)
Gauge <- gvisGauge(as.data.frame(newdf),
options=list(min=0, max=6, greenFrom=4,
greenTo=6, yellowFrom=2, yellowTo=4,
redFrom=0, redTo=2, width=400, height=300))
Gauge
})
output$map <- renderLeaflet({
leaflet(df) %>%
addTiles() %>%
addCircleMarkers(lng = ~x, lat = ~y, layerId = ~locations, color = "blue", radius = 3) %>%
addCircles(lng = ~x, lat = ~y, weight = 1,
radius = 1, label = ~locations
)
})
observeEvent(input$locations,{
updateSelectInput(session, "locations", "Click on Locations",
choices = levels(factor(df$locations)),
selected = c(input$locations))
})
observeEvent(input$map_marker_click, {
click <- input$map_marker_click
location <- df[which(df$y == click$lat & df$x == click$lng), ]$locations
updateSelectInput(session, "locations", "Click on Location",
choices = levels(factor(df$locations)),
selected = c(input$locations, location))
})
})
shinyApp(ui=ui, server = server)