R2leaflet (v0.1) – make interactive online maps from R

I have been working on a simple R function to take latitude and longitude of points of interest, and text for pop-up labels, and produce an interactive online map. Interactive graphics are incredibly useful in getting people interested in your work and communicating your data effectively, but very few statisticians / data analysts have the skills needed to make them. My aims are in this order:

  1. encourage more data people to find out about JavaScript and teach themselves some basic skills
  2. give you a really easy way of making an online interactive map

Introducing JavaScript is what it’s all about for me, so I have aimed it at newcomers. The function is called R2leaflet because it uses the popular JavaScript package leaflet to construct the map. It just takes your data and constructs a lot of text around it to form a new HTML file which contains your map. You could just upload the whole thing if you know nothing about HTML (and don’t mind having a page with a map and nothing else!), or if you are a web whizz then you will know which bits to copy and paste into your own page. It also includes a comment against each line, and the aim of that is to encourage even casual users to open the HTML file in a text editor and see how it works.

It is at a very early stage, and I have a long list of things to do to improve it, but I would value any feedback on it. You can download it from here and then load it into R by typing:
source("R2leaflet.R")

The code is at Github if you want to see how it is made and collaborate. My to-do list is there too. I encourage anyone interested in this to join me and contribute so we can make a whole suite of simple R2JS visualization functions!

Let’s look at a simple example. Below is a screenshot of the map which links to my website where you will find the real interactive version. This is simply because this blog is hosted on WordPress.com and they do not allow any JavaScript from the blogger.

mapsnap1

Here’s how it was made:

lat<-c(51.426694, 51.523242, 54.008727, 54.977433)
long<-c(-0.174015, -0.119959, -2.785206, -1.607604)
label<-c("St George's Hospital",
"UCL Institute of Child Health <br> Harvard GCSRT venue",
"Lancaster University",
"University of Northumbria <br> RSS 2013 venue")

R2leaflet(lat=lat,long=long,label=label,filename="mymap.html")

The defaults have been retained for some other arguments: map.lat and map.long, which center the map, map.zoom, which zooms in and out, and popup, which is a Boolean vector of the same length as lat, long and label, which is TRUE if you want a popup and FALSE if you don’t.

There are some neat R functions out there to make latitude and longitude from various co-ordinate systems. If you need to look up latitude and longitude for a specific few points, this website is handy. Notice how the line breaks in the popups are produced by <br>, which an HTML tag.  Want to format your text inside the popup? You can simply add HTML tags to the character vector called ‘label’. If you don’t know about HTML tags, visit this page and you’ll soon be <impressive>a web coding fiend</impressive>.

Remember that any vectors you supply to the arguments ‘lat’, ‘long’, ‘label’ and ‘popup’ will be recycled R-style if they are not the same length, with potentially disastrous results in your map! The function returns nothing at present, but you can easily change it to select from the various parts of text written to the file in a return command if that would be useful for you.

About these ads

8 Comments

Filed under R

8 responses to “R2leaflet (v0.1) – make interactive online maps from R

  1. Erik

    That’s really cool. I don’t have a use case for this yet, but I am definitely going to play around with it – nice job and thanks for sharing.

  2. Pingback: Map | m's R Blog

  3. Erin Hodgess

    Way cool! A quick question, please: what would you say would be the best way to learn javascript, please?

    • Hi Erin

      I learnt the basics from a really good and popular book “JavaScript, a beginner’s guide” by John Pollock. Once I had the basics, I found looking through the various applications people had published on GitHub, the examples at places like d3js.org, and of course viewing the source code for pages I liked, gave me insight into the different libraries – and that is an ongoing journey for me:

      O snail
      Climb Mount Fuji
      But slowly, slowly

      It would be much much harder for someone with no programming experience, e.g. an SPSS point-and-clicker, and I’m trying to work out the best way to introduce JS to such an audience in my own students…….

  4. Hi Robert,
    R2leaflet has been working really well here for several months now:
    http://www.dwa.gov.za/iwqs/microbio/report/nmmp.html
    Thank you for the example!
    – Mike

  5. Hi Robert,
    Thats quite a good example. The only point I want to express that I can not change the zoom level. Could you please check the code and let us know how to change it.
    Thanks!

    • I have changed the couple of lines in R2leaflet function. I added map.width with a default value of 800px. Thanks for sharing your code..
      R2leaflet1) {
      popup<-rep(TRUE,length(label))
      }
      head.open<-"”
      head.comment<-"
      head.css<-paste("”,sep=””)
      head.js1<-paste("”,sep=””)
      head.js2<-paste("”,sep=””)
      if (map.source==”Google”) {
      head.js3<-paste("”,sep=””)
      } else {
      head.js3<-" "
      }
      head.close<-"”
      body.open<-"”
      body.comment1<-"
      div.open<-paste("”, sep=””)
      body.comment2<-"
      div.view<-paste("var map = L.map(\'map\').setView([",
      map.lat,
      ",",
      map.long,
      "],", map.zoom,");", sep="")
      body.comment3<-"
      if (map.source==”OSM”) {
      div.tile<-"L.tileLayer(\'http://{s}.tile.osm.org/{z}/{x}/{y}.png\', { attribution: \'© OpenStreetMap contributors\’ }).addTo(map);”
      } else {
      div.tile<-c("var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');",
      "var ggl = new L.Google();",
      "map.addLayer(ggl);",
      "map.addControl(new L.Control.Layers( {'OSM':osm, 'Google':ggl}, {}));")
      }
      bindpopup<-ifelse(popup,paste(".bindPopup(",double.escape(label),")",sep=""),rep(" ",length(label)))
      body.comment4<-"
      div.mark<-paste("L.marker([",
      lat,
      ",",
      long,
      "]).addTo(map)",
      bindpopup,
      ";", sep="")
      # NB div.mark is a vector. If lat, long and label are different lengths, it will recycle them with surprising results!
      body.comment5<-"
      div.end<-"”
      body.close<-"”
      leaflet.text<-c(head.open,head.comment,head.css,head.js1,head.js2,head.js3,head.close,
      body.open,body.comment1,div.open,body.comment2,
      div.view,body.comment3,div.tile,body.comment4,
      div.mark,body.comment5,div.end,body.close)
      conn<-file(filename)
      writeLines(leaflet.text,conn)
      close(conn)
      }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s