2

I have an application that reuses several leaflet elements, so I'm trying to build functions to streamline my code.

All of my logical attempts failed, so I utilized an example I was familiar with here. I copied the format and created functions for markers and polygons, seen in the example below:

library(leaflet)
library(shiny)


markerFunction <- function(map, x, y){
  addCircleMarkers(
    map, x, y, 
    color = "red"
  )
}

polygonFunction <- function(map, polygon){
  addPolygons(
    map, polygon, 
    color = "red"
  )
}

# shinyapp 
shinyApp(
  # ui
  ui = fixedPage(
    # leaflet output 
    leafletOutput("map", height = 600)
  ),  # END UI

  # server
  server = function(input, output, session){

    # map output 
    output$map <- renderLeaflet({
      leaflet() %>% 
        addTiles
    })  # END RENDER LEAFLET 

    # map proxy
    proxy <- leafletProxy("map")

    # observe
    observe({
      proxy %>% 
        markerFunction(40, 50) %>% 
        polygonFunction(gadmCHE)
    })
  }  # END SERVER 
)

The marker function works fine, but the polygon function spits the error:

Warning: Error in derivePolygons: addPolygons must be called with both lng and lat, or with neither.

which is the error I get when I don't include data = explicitly. When I add data = polygon to the function definition and data = gadmCHE to the polygonFunction() call, I get the error:

Warning: Error in polygonFunction: unused argument (data = gadmCHE)

Running the markerFunction() on its own yields the expected result, but I'm perplexed how it works without including the map argument. When I remove it from the function, it no longer works.

I've tried many configurations and can't get any of them to work except for the markerFunction() as it exists in the above example app. I have tried including and excluding the map argument, explicitly defining other arguments (like x, y, and data) in both the function definition and function calls, excluding the explicit arguments with no luck. I want to create similar functions for polygons as well, but haven't found a solution.

  • I think you simply need data = polygon in your polygonFunction. Or you could use mapview::addFeatures instead which is feature type agnostic so should also work in the markerFunction. – TimSalabim Dec 15 '17 at 17:37
  • @TimSalabim sorry, I guess I wasn't clear. I did add data = polygon to the function and it still didn't work. I tried including it in the function definition but not the function call and vice versa, including it in both, and excluding it from both...no luck! – Lauren Dec 15 '17 at 18:01
  • 1
    For me the code runs fine when I add data = polygon only in the function definition. – TimSalabim Dec 15 '17 at 18:39
  • @TimSalabim oh, it works when I also include the map argument! Now to try my more complex example...on that note, do you have any insight why the map argument is necessary when it's never called in the function? – Lauren Dec 15 '17 at 19:43
  • 1
    It is called inherently in the pipe. The piping operator basically assumes that whatever is passed on from the previous call is used as the first argument in the subsequent call, in this case the map argument. Moreover you need to match your functions arguments to those of addPolygons which expects a map argument at first position. – TimSalabim Dec 15 '17 at 20:19
0

As @TimSalabim pointed out, the following function definition and call work (in their respective places):

polygonFunction <- function(map, polygon){
  addPolygons(
    map, data = polygon, 
    color = "red"
  )
} 


polygonFunction(gadmCHE)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.