7

I am trying to create a leaflet map with a for-loop in an rmarkdown file.

Here is a minimal example:

---
title: "Test"
output: html_document
---

```{r quakes, echo=F}
data(quakes)
library(leaflet)

for (i in c(10:20))
{
leaflet(data = quakes[1:5 & quakes$stations == i,]) %>% addTiles() %>%
  addMarkers(~long, ~lat, popup = ~as.character(mag))
}
```

I do not get any output with this code. When running the leaflet command alone (and replacing the i with an integer) it works. I also tried the print command, but that didn't work either.

Any idea how I can do this?

Afoy
  • 127
  • 5

2 Answers2

8

you have complicated it a little bit.

See you have to create a leaflet and apply markers on top of it by selecting longitudes and latitudes from unique stations.

But here you are creating leaflets in a loop. And also adding tiles in a loop which is the main problem.

Now you can create a leaflet and addTiles out of the loop and addMarkers in a loop but you dont actually need a for loop at all and add all the markers in one go.

First, Select Data Sets by Unique Stations

distinct_by_stations<-distinct(quakes,stations) #dplyr is needed for 'distinct'

Create leaflet and add markers using the above filter data set as data

leaflet(data = distinct_by_stations) %>% addTiles() %>% addMarkers(~long,~lat,popup=~as.character(mag))

See the working .rmd here at rpubs

http://rpubs.com/dhawalkapil/quakesdata

Working R Chunk

```{r quakes, echo=T}
data(quakes)
library(leaflet)
library(dplyr)

distinct_by_stations<-distinct(quakes,stations)
leaflet(data = distinct_by_stations) %>% addTiles() %>% addMarkers(~long,~lat,popup=~as.character(mag))
```

With Multiple Maps

Let's add a column on years. Then we will have to use htmltools::tagList as explained by @NicE. Split on 'year' and use lapply

```{r quakes, echo=T,results='asis'}
data(quakes)
library(leaflet)
library(dplyr)
library(htmltools)
##Add A Random Year Column
quakes$year=sample(2006:2015,length(quakes),replace=TRUE)
createMaps<-function(x){
        distinct_by_stations<-distinct(x,stations)
        lflt<-leaflet(data = distinct_by_stations) %>% addTiles() %>% addMarkers(~long,~lat,popup=~as.character(mag))
}

htmltools::tagList(lapply(split(quakes,quakes$year),function(x){createMaps(x)}))
```

See the update rpubs in the same url above.

Dhawal Kapil
  • 2,584
  • 18
  • 31
  • 3
    This makes more sense, I thought the OP wanted to create multiple maps in the loop. – NicE Feb 16 '16 at 13:32
  • thanks :D ..i figured out that..we all have done the basic mistake of initializing new objects in a loop in or other language.. – Dhawal Kapil Feb 16 '16 at 13:35
  • Well, I want to create leaflets in a loop because I want to display multiple leaflets. In the original dataset I use there is data from different years and I want to create a leaflet for every year. – Afoy Feb 16 '16 at 14:25
  • a `leaflet` is one single `map` widget. are you sure you want to create `n` maps of your `n` unique stations and on each map plot only that unique station – Dhawal Kapil Feb 16 '16 at 14:29
  • 1
    My dataset has a column here which contains years from 2006-2015. I want to create a map for every year, so I wanted to loop through the years from 2006-2015, creating a subset of every year and displaying that in the leaflet. Is that clearer? It seems like the example was not well chosen, sorry about that. I couldn't find a better dataset. – Afoy Feb 16 '16 at 14:35
  • I have tried to solve your problem by combing my solution and @NicE see the update. – Dhawal Kapil Feb 16 '16 at 16:12
  • I get an error: > htmltools::tagList(lapply(split(quakes,quakes$year),function(x){createMaps(x)})) Error in eval(expr, envir, enclos) : object 'long' not found – jzadra Apr 06 '17 at 16:02
  • This is because distinct() drops the lat and long columns by default. You can address it by adding the keep_all argumnet, i.e.: distinct_by_stations<-distinct(x,stations,.keep_all = TRUE) – John May 09 '20 at 05:16
5

You can use tagList from htmltools:

library(htmltools)
maps <- lapply(c(unique(quakes$stations)),function(x){
    leaflet(data = quakes[1:5 & quakes$stations == x,]) %>% addTiles() %>%
  addMarkers(~long, ~lat, popup = ~as.character(mag))    
})

tagList(maps)

It takes a list as argument so I changed your for loop to a lapply.

NicE
  • 21,165
  • 3
  • 51
  • 68