0
map_basic <- leaflet::leaflet() %>%
             leaflet::addMarkers(
                data = flow_stations,
                group = "Stream Flow Stations",
                options = leaflet::leafletOptions(pane="marker"),                    
                label = paste0(flow_stations$`Data Source`, ": ", flow_stations$Station, " (", flow_stations$`Station ID`,")"),
                labelOptions = labelOptions(textsize = "15px"),
                popup = ~paste0("<b>", 
                                flow_stations$`Data Source`," Station Name: ",
                                flow_stations$Station,"<br>",
                                "Station ID: ", flow_stations$`Station ID`,
                                sapply(flow_stations$Station, 
                                       popupTable.flow, USE.NAMES = FALSE)),
                popupOptions = leaflet::popupOptions(maxWidth = 650, maxHeight = 300))

In above codes, can I save the arguments in an object and use the object inside the function of leaflet::addMarkers( )? For example,

flowStations <- paste0(
                   'data = flow_stations,',
                   'group = "Stream Flow Stations",',
                   'options = leaflet::leafletOptions(pane="marker"),',                       
                   'label = paste0(flow_stations$`Data Source`, ": ", flow_stations$Station, " (", flow_stations$`Station ID`,")"),',
                   'labelOptions = labelOptions(textsize = "15px"),',
                   'popup = ~paste0("<b>", ',
                                   'flow_stations$`Data Source`," Station Name: ",',
                                   'flow_stations$Station,"<br>",',
                                   '"Station ID: ", flow_stations$`Station ID`,',
                                   'sapply(flow_stations$Station, ',
                                          'popupTable.flow, USE.NAMES = FALSE)),',
                   'popupOptions = leaflet::popupOptions(maxWidth = 650, maxHeight = 300)')

then, simplify the codes to something like below for testing.

map_basic <- leaflet::leaflet() %>%
             leaflet::addMarkers(flowStations)

The error message of the testing codes is

Error in derivePoints(data, lng, lat, missing(lng), missing(lat), "addMarkers") : Point data not found; please provide addMarkers with data and/or lng/lat arguments

Anyone have an idea to make it work, please kindly share. Thanks!

** Update ****************************************************************

Thanks for all your suggestions. I am adding a very simple reproducible script here below.

Station <- c("Station 1","Station 2")
Lat <- c("45.11373","45.07123")
Long <- c("-121.8151","-121.9406")
flow_stations <- data.frame(Station, Lat, Long) %>% 
   sf::st_as_sf(coords = c("Long","Lat"), crs = sf::st_crs("+init=EPSG:4326"))

map_basic <- leaflet::leaflet() %>%
   leaflet::addMarkers(data = flow_stations,
                       label = flow_stations$Station)

I tried to extra the parameters into a list.

flowStations <- list("data = flow_stations",
                     "label = flow_stations$Station")

Then tried below based on @r2evans's suggestion.

map_basic <- leaflet::leaflet() %>%
   do.call(leaflet::addMarkers,flowStations)

I got the error:

Error in do.call(., leaflet::addMarkers, flowStations) : second argument must be a list

I probably didn't use do.call correctly. More suggestions?

3
  • It's easier to help you if you include a simple reproducible example with sample input that can be used to test and verify possible solutions.
    – MrFlick
    Commented Oct 31, 2021 at 21:29
  • 1
    Why are you trying to save just the parameter of addMarkers and not the entire call to addMarkers? Is there a reason you don't want to just write a normal function to help with this?
    – MrFlick
    Commented Oct 31, 2021 at 21:30
  • Yes, @MrFlick. I will place the flow_station markers to multiple maps. Therefore, if I can extract the parameters of 'addMarkers', the call will look cleaner and shorter. I don't want to repeat 'addMarkers' with a long list of parameters in each map. But actually I am not sure if that's possible. :-) Let me see if I can add a reproducible script. Thanks for helping.
    – Angel
    Commented Nov 1, 2021 at 6:01

2 Answers 2

0

Rather than storing cpde as strings, you can write a helper function. For example

myAddMarkers <- function(plot, data) {
  leaflet::addMarkers(
    plot, data = data,
    group = "Stream Flow Stations",
    options = leaflet::leafletOptions(pane = "marker"),
    label = paste0(data$`Data Source`,": ", data$Station," (", data$`Station ID`,")"),
    labelOptions = labelOptions(textsize = "15px"),
    popup = ~ paste0(
      "<b>", data$`Data Source`,
      " Station Name: ", data$Station, "<br>",
      "Station ID: ", data$`Station ID`,
      sapply(data$Station, popupTable.flow, USE.NAMES = FALSE)
    ),
    popupOptions = leaflet::popupOptions(maxWidth = 650, maxHeight = 300)
  )
}

Then for all the plots you want to use these setting, you can use

map_basic <- leaflet::leaflet() %>% myAddMarkers(flow_stations)
1
  • Yeah! It works! Thank you very much @MrFlick! I really appreciate your help. This will greatly condense the code lines.
    – Angel
    Commented Nov 1, 2021 at 6:51
0

If you save the arguments as a list (not a character string), you can use do.call(). Your code is not replicable, but here's an example showing the idea:

args = list(
  x = 1:10,
  y = 2:20
)

do.call(what = t.test, args = args)

which will call the function t.test with the named arguments in args.

4
  • Thanks Richard. Sorry my codes are not replicable. I just wanted to show an idea of my codes. I am not sure how to use do.call( ) in the leaflet process. In order to add markers to the map, I believe addMarkers( ) need to be outside the do.call( ), which makes do.call( ) doesn't work in my case. Do I miss anything here?
    – Angel
    Commented Oct 31, 2021 at 21:25
  • Perhaps leaflet::leaflet() %>% list(.) %>% do.call(leaflet::addMarkers, .)
    – r2evans
    Commented Oct 31, 2021 at 23:10
  • Thanks @r2evans. I firstly saved the list to the object flowStations, then I used leaflet::leaflet( ) %>% do.call(leaflet::addMarkers, flowStations) and I got the error: "Error in do.call(., leaflet::addMarkers, flowStations) : second argument must be a list". I am not sure why do.call( ) function doesn't take leaflet::addMarkers as a function.
    – Angel
    Commented Nov 1, 2021 at 5:50
  • This has to do with the fact that the pipe %>% is still passing in the first argument. You want something like args = list(map = leaflet::leaflet(), data = flow_stations, [etc]); do.call(leaflet::addMarkers, args); Commented Nov 2, 2021 at 8:15

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