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
Posted in Uncategorized

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 )

Google+ photo

You are commenting using your Google+ 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 )

w

Connecting to %s

Categories
Follow TomazTsql on WordPress.com
Revolutions

Tomaz doing BI and DEV with SQL Server and R

tenbulls.co.uk

attaining enlightenment with sql server, .net, biztalk, windows and linux

SQL DBA with A Beard

He's a SQL DBA and he has a beard

DB NewsFeed

Matan Yungman's SQL Server blog

Reeves Smith's SQL & BI Blog

A blog about SQL Server and the Microsoft Business Intelligence stack with some random Non-Microsoft tools thrown in for good measure.

SQL Server

for Application Developers

Clocksmith Games

We make games we love to play

Business Analytics 3.0

Data Driven Business Models

SQL Database Engine Blog

Tomaz doing BI and DEV with SQL Server and R

Search Msdn

Tomaz doing BI and DEV with SQL Server and R

R-bloggers

Tomaz doing BI and DEV with SQL Server and R

Ms SQL Girl

Julie Koesmarno's Journey In Data, BI and SQL World

R-bloggers

R news and tutorials contributed by (750) R bloggers

Data Until I Die!

Data for Life :)

Paul Turley's SQL Server BI Blog

sharing my experiences with the Microsoft data platform, SQL Server BI, Data Modeling, SSAS Design, Power Pivot, Power BI, SSRS Advanced Design, Power BI, Dashboards & Visualization since 2009

Grant Fritchey

Intimidating Databases and Code

Madhivanan's SQL blog

A modern business theme

Alessandro Alpi's Blog

SQL Server, Azure and .net in a nutshell :D

Paul te Braak

Business Intelligence Blog

Sql Server Insane Asylum (A Blog by Pat Wright)

Information about SQL Server from the Asylum.

Gareth's Blog

A blog about Life, SQL & Everything ...

SQLPam's Blog

Life changes fast and this is where I occasionally take time to ponder what I have learned and experienced. A lot of focus will be on SQL and the SQL community – but life varies.

William Durkin

William Durkin a blog on SQL Server, Replication, Performance Tuning and whatever else.

$hell Your Experience !!!

As aventuras de um DBA usando o Poder do $hell

%d bloggers like this: