0
votes

I am attempting to create a Shiny app using R that plots coordinate data on a map via leaflet. The data also has date stamps, and I want to be able to plot a specific days' coordinates as chosen by the user. I'm brand new to both R and Shiny so all help is appreciated. Here is a snippet of the dataframe;

 Date    |   InitialLat | InitialLong |    NewLat   |  NewLong  |
13/05/16 |   53.477403  | -2.230932   |  51.527953  | -0.13216  |
13/05/16 |   53.490599  | -2.312568   |  53.485655  | -2.237405 |
14/05/16 |   53.371535  | -2.23148    |  53.32803   | -2.246991 |
14/05/16 |   53.371535  | -2.23148    |  53.32803   | -2.246991 |
15/05/16 |   53.371535  | -2.23148    |  53.32803   | -2.246991 |
15/05/16 |   53.371535  | -2.23148    |  53.32803   | -2.246991 |
16/05/16 |   53.478316  | -2.23270    |  53.42814   | -2.17458  |
16/05/16 |   53.48868   | -2.21839    |  53.47737   | -2.23091  |

My code so far:

library(shiny)
library(leaflet)

cleanData <- read.csv(file="CleanedJourneyData.csv", header=TRUE, sep=",")
cleanData$X <- NULL

ui <- fluidPage(
  dateInput(inputId = "n_date", label="Select a date", value = "2016-05-13", min = "2016-05-13", max = "2016-10-24",
            format = "dd-mm-yyyy", startview = "month",
            language = "en", width = NULL),
  leafletOutput("map")

)

server <- function(input, output, session) {

  dailyData <- reactive(cleanData[cleanData$Date == format(input$n_date, '%d/%m/%y')] )

  output$map <- renderLeaflet({  leaflet(dailyData) %>% addTiles() %>% 
      addMarkers(~InitialLong, ~InitialLat, popup = "Start")  })
}

shinyApp(ui, server)

The problem lies in the line;

dailyData <- reactive(cleanData[cleanData$Date == format(input$n_date, '%d/%m/%y')] )

The error I get is:

Error: no applicable method for 'doResolveFormula' applied to an object of class "reactive"

What I'm trying to achieve is;

  • the user selects a date
  • the format of the date is changed to '%d/%m/%y'
  • the inputted date is then used to search the dataframe (cleanData) to create a new dataframe (dailyData) of just the lat/long coordinates from that selected date
  • the trimmed down dataframe is inputted into the leaflet map and displayed

The date input works fine, I can get the date in the right format, but when I try and use this to search cleanData to create the dailyData it doesn't work, and I cannot figure it out. What am I doing wrong? For the record I was able to get this to work outside of Shiny - I manually changed the date in the code and the corresponding coordinates were plotted through the leaflet.

2
there is an error in your reactive function. It should be reactive({})..curly braces are missing - MLavoie
A reactive is a function that returns data, not data itself. To get the data, call it like this leaflet(dailyData()) - HubertL

2 Answers

1
votes

I have modified your code. Just have a look if this is what you really want.

library(shiny)
library(leaflet)

cleanData <- read.csv(file="D:/CleanedJourneyData.csv", header=TRUE, sep=",")
cleanData$X <- NULL

ui <- fluidPage(
  dateInput(inputId = "n_date", label="Select a date", value = "2016-05-13", min = "2016-05-13", max = "2016-10-24",
            format = "dd-mm-yyyy", startview = "month",
            language = "en", width = NULL),
  leafletOutput("map")

)

server <- function(input, output, session) {

  dailyData <- reactive(cleanData[cleanData$Date == format(input$n_date, '%d/%m/%y'), ] )

  # I have implemented the change here, instead of using dailyData, I've used isolate(dailyData())
  output$map <- renderLeaflet({ leaflet(isolate(dailyData())) %>% addTiles() %>% 
                                   addMarkers(~InitialLong, ~InitialLat, popup = "Start")  })

}

shinyApp(ui, server)

Hope it helps!

0
votes

With help from a colleague well-versed in R I have found the answer to my question;

cleanData <- read.csv(file="/Users/CharlesPowell/R/CleanedJourneyData.csv", header=TRUE, sep=",")
cleanData$X <- NULL

r_colors <- rgb(t(col2rgb(colors()) / 255))
names(r_colors) <- colors()

ui <- fluidPage(
  dateInput(inputId = "n_date", label="Select a date", value = "2016-05-13", min = "2016-05-13", max = "2016-10-24",
            format = "dd-mm-yyyy", startview = "month",
            language = "en", width = NULL),
  leafletOutput("map")

)

server <- function(input, output, session) {

  numrow <- reactive({cleanData$Date == format(input$n_date, '%d/%m/%y')})
  dailyData <- reactive({cbind(cleanData[numrow(),], Observation = seq(1:sum(numrow())))})

  z <- reactive({as.data.frame(gather(data=dailyData()[, 2:dim(dailyData())[2]], measure, val, -Observation) %>% group_by(Observation) %>%
    do(data.frame(   lat=c(.[["val"]][.[["measure"]]=="InitialLat"],
                           .[["val"]][.[["measure"]]=="NewLat"]),
                     long = c(.[["val"]][.[["measure"]]=="InitialLong"],
                              .[["val"]][.[["measure"]]=="NewLong"]))))})

  y <- reactive({points_to_line(z(), "long", "lat", "Observation")})

  output$map <- renderLeaflet({ leaflet(dailyData()) %>% addTiles() %>% 
      addMarkers(~InitialLong, ~InitialLat, popup = "Start") %>%
    addPolylines(data = y()) })

}

shinyApp(ui, server)

You can see that I've also added in functionality to create point-to-point lines using the function created by Kyle Walker. https://rpubs.com/walkerke/points_to_line

So now when I change the inputted date, that date's corresponding data is plotted on a leaflet map with lines connecting the start and end points.