Plotting Customer Addresses on GoogleMaps using R

Customer data (in typical CRM system) usually consist of addresses, demographics and purchase behavior. Let’s say, we have a case that I want to plot all customers that made purchases in a particular shop. Based on that I can make further analysis on where do my customers come from, do concentric circles analysis and  see which parts are not covered.

First obstacle are addresses. We get customer addresses in “readable” format of: Street Name, Street Number, ZIP Code, City. But if we want to plot massive amount of addresses on any kind of map, we need these addresses to be converted to geocodes.

R supports a nice way to convert your customer addresses into geo codes locations (I have done this without using HML language).

I have prepared mockup data (based on existing addresses) for this blog post.

   CUSTOMER_ID           STREET STREET_NUMBER POST_CODE      CITY CUSTOMER_COUNTRY
1            1 TOLSTOJEVA ULICA            35      1000 LJUBLJANA               SI
2            2 GLAVARJEVA ULICa            44      1000 LJUBLJANA               SI
3            3  MAROLTOVA ULICA             4      1000 LJUBLJANA               SI
4            4   DIMIČEVA ULICA            10      1000 LJUBLJANA               SI
5            5 TREBINJSKA ULICA            16      1000 LJUBLJANA               SI
6            6 MARIBORSKA ULICA             7      1000 LJUBLJANA               SI
7            7    PTUJSKA ULICA             2      1000 LJUBLJANA               SI
8            8 NOVINARSKA ULICA             2      1000 LJUBLJANA               SI
9            9         PEGAMOVA             3      1000 LJUBLJANA               SI
10          10  VODOVODNA ULICA            16      1000 LJUBLJANA               SI
11          11   DUNAJSKA CESTA           106      1000 LJUBLJANA               SI
12          12   DUNAJSKA CESTA           104      1000 LJUBLJANA               SI

These mockup data is available here in CSV file (csv as docx format: customer_address_list_LJ.csv).

Insert csv into data.frame in R.

address_LJ <- read.csv("customer_address_list_LJ.csv", sep=",", quote = "\"")

Using XmlParseTree method in XML Library I looped through the addresses and converted them into geo codes.

for(i in 1:nrow(address_LJ)) {
  Customer_rk <- address_LJ$CUSTOMER_RK[i]
  url <- paste('http://maps.googleapis.com/maps/api/geocode/xml?address=',
               str_replace_all(address_LJ$STREET_NUMBER[i]," ","+"),
               ",+",str_replace_all(address_LJ$STREET[i]," ","+"),",+",str_replace_all(address_LJ$CITY[i]," ","+"),",+",
               str_replace_all(address_LJ$POST_CODE[i]," ","+"), ",+CA&sensor=true")

  f <- xmlTreeParse(url, useInternal=TRUE)
  lat <- as.numeric(xmlValue(getNodeSet(f, '//location/lat')[[1]]))
  lng <- as.numeric(xmlValue(getNodeSet(f, '//location/lng')[[1]]))
  
  results_LJ <- rbind(results_LJ,c(Customer_rk, lat, lng))
}

URL address should be presented in format of:

http://maps.googleapis.com/maps/api/geocode/xml?address=8,+MAROLTOVA+ULICA,+LJUBLJANA,+1000,+CA&sensor=true

and by concatenating the string and populating it with values from the data.frame the loop passes the URL to googleAPI and returning the latitude and longitude.

Once I have geo codes returned I can focus on map. Focusing on Ljubljana (my home town) I use following code:

# Ljubljana
Customer_map <- GetMap(center = c(lat = 46.05, lon = 14.5), zoom = 12, destfile = "LJ_8A.png", 
                     maptype = "terrain")

LJ_8

And since I want map to be more zoomed in I increase zoom parameter and detailed the lat and lon parameters, resulting in following code:

# North part of Ljubljana
Customer_map <- GetMap(center = c(lat = 46.077, lon = 14.507), zoom = 15, destfile = "LJ_8B.png", 
                     maptype = "terrain")

Getting following image:

LJ_8B

Now that zoom level is satisfying, I can plot my customer locations (red markers) and my store (blue marker) to have a better visual presentation of how far, where and how many customers are visiting my shop. (please keep in my this is mockup data!)

#Map of Ljubljana and customer data
Customer_map <- GetMap(center = c(lat = 46.077, lon = 14.507), zoom = 15, destfile = "Lj_15.png", 
                     maptype = "terrain", 
                     markers = paste0("&markers=color:red|46.0770269,14.5077839&markers=color:red|46.0753567,14.5057188&markers=color:red|46.0805885,14.5187349
                                      &markers=color:red|46.071167,14.5127886&markers=color:red|46.0791308,14.5168944&markers=color:red|46.0684584,14.5114233
                                      &markers=color:red|46.0695977,14.5107855&markers=color:red|46.0736024,14.507131&markers=color:red|36.778261,-119.4179324
                                      &markers=color:red|46.0676479,14.508059,&markers=color:red|46.0744262,14.5119666,&markers=color:red|46.0734664,14.5118505
                                      &markers=color:blue|label:SH1|46.0765772,14.5076201")
                      ) 

Same map is now presented with markers.

Lj_15

Now it is up to you to do further analysis and assumption based on such map analysis.

Complete R code.

###################################
# Customer address  Visualization
# on google maps
# on case of Retail shop
###################################

setwd("C:/DataTK/address2GeoCode")

library(XML)
library(stringr)
library(RgoogleMaps)


# Customer Data
address_LJ <- read.csv("customer_address_list_LJ.csv", sep=",", quote = "\"")


# Empty data.frame for storing geo codes
results_LJ <- data.frame(Customer_rk = numeric(0), lat = numeric(0), lng = numeric(0))

for(i in 1:nrow(address_LJ)) {
  Customer_rk <- address_LJ$CUSTOMER_RK[i]
  url <- paste('http://maps.googleapis.com/maps/api/geocode/xml?address=',
               str_replace_all(address_LJ$STREET_NUMBER[i]," ","+"),
               ",+",str_replace_all(address_LJ$STREET[i]," ","+"),",+",str_replace_all(address_LJ$CITY[i]," ","+"),",+",
               str_replace_all(address_LJ$POST_CODE[i]," ","+"), ",+CA&sensor=true")

  f <- xmlTreeParse(url, useInternal=TRUE)
  lat <- as.numeric(xmlValue(getNodeSet(f, '//location/lat')[[1]]))
  lng <- as.numeric(xmlValue(getNodeSet(f, '//location/lng')[[1]]))
  
  results_LJ <- rbind(results_LJ,c(Customer_rk, lat, lng))
  
}

#export results to CSV
write.csv(results_LJ, file = "rezultati_customer_address_LJ_lat_lng.csv")

#markers embedded into plot
rm(markers_map)
for (i in 1:nrow(results_LJ))
{
  
  markers_map <- paste('&markers=color:red|',results_LJ$X46.0770269,",",results_LJ$X14.5077839,",")
  markers_map <- rbind(markers_map, paste('&markers=color:red|',results_LJ$X46.0770269,",",results_LJ$X14.5077839))
}

### VISUALIZATION

# Ljubljana
Customer_map <- GetMap(center = c(lat = 46.05, lon = 14.5), zoom = 12, destfile = "LJ_8.png", 
                     maptype = "terrain")
                     
# North part of Ljubljana
Customer_map <- GetMap(center = c(lat = 46.077, lon = 14.507), zoom = 15, destfile = "LJ_8B.png", 
                     maptype = "terrain")

#Map of Ljubljana and customer data
Customer_map <- GetMap(center = c(lat = 46.077, lon = 14.507), zoom = 15, destfile = "Lj_15.png", 
                     maptype = "terrain", 
                     markers = paste0("&markers=color:red|46.0770269,14.5077839&markers=color:red|46.0753567,14.5057188&markers=color:red|46.0805885,14.5187349
                                      &markers=color:red|46.071167,14.5127886&markers=color:red|46.0791308,14.5168944&markers=color:red|46.0684584,14.5114233
                                      &markers=color:red|46.0695977,14.5107855&markers=color:red|46.0736024,14.507131&markers=color:red|36.778261,-119.4179324
                                      &markers=color:red|46.0676479,14.508059,&markers=color:red|46.0744262,14.5119666,&markers=color:red|46.0734664,14.5118505
                                      &markers=color:blue|label:SH1|46.0765772,14.5076201")
                      ) 

This code snippet can easily be imported into SQL Server 2016 (current version CTP 3.0) and used for data presentation in SQL Server Reporting Services or Power BI environment.

Happy coding!

Advertisements

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