I want to create a shiny app that takes the first date range as inputs for the SQL command to query from the RSQLite db I created. However, when I run this without having a df object prior to running the app, it does not work. If I try to update the long lat slider ranges that are currently commented out, this crashes the app. I also keep getting this error: Warning in if (!loaded) { : the condition has length > 1 and only the first element will be used c("Loading required package: [", "Loading required package: input$timestamp", "Loading required package: 1") Failed with error: ‘'package' must be of length 1’
Can anyone help? I just want the user to give me the first date and last date ranges to query the database and then have dplyr do the rest of the filtering.
library(dplyr)
library(htmltools)
library(leaflet)
library(leafem)
library(shiny)
library(shinyjs)
library(shinyWidgets)
library(shinythemes)
library(shinyBS)
#Create a formatted timestamp for filename
humanTime <- function() format(Sys.time(), "%Y-%m-%d_%H-%M-%OS")
#Create a Dummy Dataset
get_data <- function(size){
df <- data.frame(OBJECT_ID = seq(from =1, to = size, by = 1))
df$LONGITUDE <- sample(seq(from=-20, to =160, by = 0.01), size, rep= TRUE)
df$LATITUDE <- sample(seq(from = -10, to= 83, by = 0.01), size, rep= TRUE)
df$LOCATION <- sample(c("A", "B", "C"), size, replace = T, prob = c(0.4, 0.4, 0.2))
df$EQUIPMENT <- sample(c("E1", "E2", "E3", "E4"), size, replace = TRUE)
startTime <- as.POSIXct("2016-01-01")
endTime <- as.POSIXct("2019-01-31")
df$DATE <- as.character(as.Date(sample(seq(startTime, endTime, 1), size))) #use as.Date to remove times
df$WEEKDAY <- weekdays(as.Date(df$DATE))
return(df)
}
#Is this necessary to get the ranges for the slider values?
df <- get_data(200)
df$DATE <- as.Date(df$DATE)
df <- df %>% mutate_if(is.character, as.factor)
ui <- navbarPage(
id = "navBar",
title = "Data Exploration",
theme = shinytheme("cerulean"),
shinyjs::useShinyjs(),
selected = "Data",
tabPanel("Data",
fluidPage(
sidebarPanel(
div(id = "form",
dateRangeInput('timestamp', label = 'Date range input:', start = '', end = ''),
pickerInput('days_of_week', 'Choose Weekdays:', choices = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"), options = list(`actions-box` = TRUE), multiple = T),
sliderInput('long', "Longitude Range:", min = min(df$LONGITUDE),max = max(df$LONGITUDE), value = c(min(df$LONGITUDE), max(df$LONGITUDE)), step = 0.1),
sliderInput('lat', "Latitude Range:", min = min(df$LATITUDE),max = max(df$LATITUDE), value = c(min(df$LATITUDE), max(df$LATITUDE)), step = 0.1),
pickerInput('location', "Select Location:", choices = unique(df$LOCATION), options = list(`actions-box` = TRUE), multiple = T),
pickerInput('equipment_type', "Choose Equipment:", choices = unique(df$EQUIPMENT), options = list(`actions-box` = TRUE), multiple = T),
actionButton("resetAll", "Reset Filters"),
selectInput("download_type", "Choose download formatt:", choices = c("CSV" = ".csv", "KML" = ".KML")))
),
mainPanel(
leafletOutput("datamap", width = "100%", height = 400),
DT::DTOutput('datatable')))
)
)#end the ui
server <- function(session, input, output){
filter_by_dates <- reactive({
require(input$timestamp[1])
require(input$timestamp[2])
my_conn <- dbConnect(RSQLite::SQLite(), "sample.db")
df <- DBI::dbGetQuery(my_conn, paste0("SELECT * FROM Table_1 WHERE DATE >= '", input$timestamp[1], "' AND DATE <= '", input$timestamp[2], "'"))
df$DATE <- as.Date(df$DATE)
df <- df %>% mutate_if(is.character, as.factor)
DBI::dbDisconnect(my_conn)
return(df)
})
filter_by_all <- reactive({
fd <- filter_by_dates()
if (!is.null(input$days_of_week)) {
fd <- filter(fd, WEEKDAY %in% input$days_of_week)
}
if (!is.null(input$long[1] & input$long[2])){
fd <- filter(fd, LONGITUDE >= input$long[1] & LONGITUDE <= input$long[2])
}
if (!is.null(input$lat[1] & input$lat[2])){
fd <- filter(fd, LATITUDE >= input$lat[1] & LATITUDE <= input$lat[2])
}
if (!is.null(input$location)) {
fd <- filter(fd, LOCATION %in% input$location)
}
if (!is.null(input$equipment_type)) {
fd <- filter(fd, EQUIPMENT %in% input$equipment_type)
}
return(fd)
})
observe({
require(input$timestamp[1])
require(input$timestamp[2])
updatePickerInput(session, 'days_of_week', 'Choose Weekdays:', choices = sort(unique(filter_by_all()$WEEKDAY), decreasing = T), selected = sort(input$days_of_week, decreasing = T))
#updateSliderInput(session, 'long', "Longitude Range:", min=min(filter_by_all()$LONGITUDE), max = max(filter_by_all()$LONGITUDE), value = c(input$long[1], input$long[2]))
#updateSliderInput(session, 'lat', "Latitude Range:", min=min(filter_by_all()$LATITUDE), max = max(filter_by_all()$LATITUDE), value = c(input$lat[1], input$lat[2]))
updatePickerInput(session, 'location', "Select Location:", choices = unique(filter_by_all()$LOCATION), selected = input$location)
updatePickerInput(session, 'equipment_type', "Choose Equipment:", choices = unique(filter_by_all()$EQUIPMENT), selected = input$equipment_type)
})
#Map is updated by User inputs
output$datamap <- renderLeaflet({
leaflet(data = filter_by_all() ) %>%
addCircleMarkers(
lng = ~LONGITUDE,
lat = ~LATITUDE,
radius = 3) %>%
addTiles(group = "ESRI") %>%
addTiles(group = "OSM") %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI") %>%
addProviderTiles("Stamen.Toner", group = "Stamen") %>%
addLayersControl(baseGroup = c("ESRI", "OSM", "Stamen"))
})
output$datatable <- DT::renderDT({
filter_by_all()
}, server = FALSE) #this was used with SharedData doesn't work with downloading data so scrap
#Allow the user to reset all their inputs
observeEvent(input$resetAll, {
reset("form")
})
}#end server
shinyApp(ui, server)