4
votes

Background

I have to create a prototype map based dashboard for a project. I decided on R shiny, as it had the best data management for my data, and easy to use. I use Leaflet in combination with Rshiny. After creating the map, it gets updated at certain intervals and recreates the map with new data (kind off batch real time). The data will be quite a lot, but is still manageable on a leaflet application.

Code:

library(shinydashboard)
library(leaflet)

ui <- fluidPage(
  dashboardBody(
    box(width = NULL, solidHeader = TRUE,
                 leafletOutput("busmap", height = 900)
    )
  )
)

server <- function(input, output) {

liveish_data <- reactive({
    invalidateLater(6000)
    lat <- runif(3000, min=51, max=53.5)
    lon <- runif(3000, min=4, max=8)
    DF_Actueel <- data.frame(lat,lon)
    print("refreshed")
    DF_Actueel
  })

  output$busmap = renderLeaflet({
    DF_Actueel <- liveish_data()
    map <- leaflet(options=list())%>%
      addProviderTiles(providers$OpenStreetMap.HOT) %>%
      addMarkers(data = DF_Actueel)

    map
  })
}

shinyApp(ui, server)

Issue

I was checking my taks manager while running the app. My problem is that when this app is run, RStudio uses some memory (approximately 350MB on my pc), and every time it updates, the memory usage of Rshiny increases by 20MB.

> object.size(map)
148000 byte

This means after a few minutes, Rstudio runs out of memory. I have given it more memory... but that just means it runs out later.

Own Research

I have looked at similar questions:

Shiny R reactivevalues memory leak -- Unanswered

https://github.com/rstudio/shiny/issues/1551 -- Used the Observe() function

https://github.com/rstudio/shiny/issues/1591 -- I used the options(shiny.reactlog=TRUE) and check the output. I have only one map object

https://github.com/rstudio/shiny/issues/1151 -- Used Plotly instead of leaflet and was not solved, even though it was closed.

There was some more along the same topics and same unanswered questions.

Specifications

Windows 10
24GB RAM
64-bit operating system
Intel(R) Core i7-6700HQ CPU @ 2.6GHz
R version 3.4.3 (2017-11-30)
leaflet 1.1.0
shinydashboard 0.6.1

I hope someone can help. Thank you :)

1
Tried (unsuccesfully) to fix it. My line of thought was based on noticing that every time renderleaflet is called, it is as a new environment. Therefore map cannot be overwritten because R sees as another variable defined in another environment. Sadly deleting manully (with rm()) the variable from the original environment did not change anything: the variable must be persisted elsewherein the depth of shiny's guts. I would suggest to post it in github - shiny issues.Enzo

1 Answers

1
votes

I moved the addMarkers to a leafletProxy, so that the map is not newly rendered and loaded to in-memory at all 6 seconds. And i think if you use clearMarkers() just before you add the new markers, the memory should stay more or less stable.

Here is the code:

library(shinydashboard)
library(leaflet)

ui <- fluidPage(
  dashboardBody(
    box(width = NULL, solidHeader = TRUE,
        leafletOutput("busmap", height = 900)
    )
  )
)

server <- function(input, output) {

  liveish_data <- reactive({
    invalidateLater(6000)
    lat <- runif(3000, min=51, max=53.5)
    lon <- runif(3000, min=4, max=8)
    DF_Actueel <- data.frame(lat,lon)
    print("refreshed")
    DF_Actueel
  })

  output$busmap = renderLeaflet({
    map <- leaflet(options=list())%>%
      addProviderTiles(providers$OpenStreetMap.HOT)
    map
  })

  observe({
    DF_Actueel <- liveish_data()
    leafletProxy("busmap", deferUntilFlush=T) %>% 
      clearMarkers() %>% 
      addMarkers(data = DF_Actueel)
  })
}

shinyApp(ui, server)