Mapping Walmart store closures in R

David Radcliffe
February 18, 2016

Revised March 23, 2016

Introduction

On January 15, 2016, Walmart announced that it will close 269 stores worldwide, including 154 stores in the United States. The closures will impact 16,000 workers.

The locations of store closings in the United States were listed on the corporate website. I thought that it would be interesting to see the locations on a map.

Map of Walmart Store Closings

The “live” map is at http://rpubs.com/Radcliffe/walmart.

Walmart Map

R packages used

  • rvest for web scraping.
  • dplyr for data manipulation.
  • stringr for string manipulation.
  • ggmap for geocoding.
  • leaflet to create an interactive map.

Acquire the data

The first step is to read the data from Walmart's website.

url <- "http://j.mp/walmart-closed"
webpage <- xml2::read_html(url)

Walmart Data

Convert to a data frame

We use rvest to extract the table and convert it to a data frame.

library(rvest)
library(dplyr)

df <- webpage %>%
  html_node('table') %>%
  html_table()

Notes:

  • html_node accepts any CSS or XPATH selector.
  • Use html_nodes to retrieve multiple elements.

Viewing the raw data

Raw Walmart Data

Cleaning the data

  1. Move data from columns 3 and 4 into columns 1 and 2.
  2. Set appropriate column names.
  3. Remove rows without store locations.
  4. Extract the store numbers.
  5. Extract the street addresses.
  6. Set the store types (Wal-Mart, Supercenter, etc.)
  7. Parse the closing dates

Data cleaning - R code

First, we move the data from columns 3 and 4 into columns 1 and 2, and we remove lines that do not contain store locations.

df <- 
  data.frame(
      Location = c(df$X1, df$X3),
      DateClosed = c(df$X2, df$X4)) %>%
  filter(grepl("^#", Location))

Data cleaning - More R code

Next, we extract the store numbers and street addresses. We also convert the dates into a standard format.

require(stringr)

df <- mutate(df, 
  StoreNumber = 
    str_extract(Location, "[0-9]+"),
  Location = 
    gsub("^#[0-9]+[:,]? ", "", 
         Location),
  DateClosed = 
    as.Date(DateClosed, "%m/%d/%Y"))

Setting the store types

When viewing the raw data, I counted the number of stores of each type – Wal-mart, Walmart Express, etc. I use this information to assign the store types.

df$StoreTypes <- c(
  rep("Walmart Express", 102),
  rep("Wal-Mart", 6),
  rep("Supercenter", 12),
  rep("Neighborhood Market", 23), 
  rep("Amigo", 7), 
  rep("Sam's Club", 4))

Geocoding the locations

We need to look up the latitude and longitude of each store location to display them on a map. The ggmap package makes this easy.

library(ggmap)
latlng <- geocode(df$Location)
df[which(is.na(latlng$lon)), ]
latlng[146, ] <- geocode('Coama, PR')
latlng[148, ] <- geocode('Rio Grande, PR')
latlng[149, ] <- geocode('Salinas, PR')
df <- cbind(df, latlng)

By default, geocode uses the Google Maps API, and it returns only the latitude and longitude. It has options to return more detailed information.

Create the map

We use the leaflet to create the map. The leaflet project has a fork that adds support for more kinds of markers.

First, let's create an empty map without any markers.

devtools::install_github('bhaskarvk/leaflet') 
library(leaflet)

m <- leaflet() %>%
  addTiles() %>%
  setView(lng=-90, lat=40, zoom=5)

Create the markers

We create a set of map markers with different colors, depending on store type.

markerColorList <- list(
  "Walmart Express" = "blue",
  "Wal-Mart" = "red",
  "Supercenter" = "green",
  "Neighborhood Market" = "orange",
  "Amigo" = "purple",
  "Sam's Club" = "black")

df$color <- unlist(markerColorList[df$StoreType])
markers <- awesomeIcons(
  icon='map-marker',
  markerColor = df$color,
  library='glyphicon')

Create the popups

We want a popup to appear when the user clicks on a marker. The popup can contain HTML formating and hyperlinks.

popups <- paste0(
  "<b>", 
  df$StoreType, 
  "</b><br>", 
  df$Location, 
  "<br>",
  "Date closed: ",
  df$DateClosed)

Add markers and popups to the map

m %>%
  addAwesomeMarkers(
    lng=df$lon,
    lat=df$lat,
    icon=markers,
    popup=popups,
    clusterOptions = markerClusterOptions()) %>%
  addLegend(
    position='topright', 
    colors=markerColorList,
    labels=names(markerColorList),
    title="Walmart Store Closings in 2016")

Publish the map

Once the map is displayed in RStudio, we can publish it to RPubs by clicking on the Publish button, or we can export the map to HTML.

Publish map

Thanks!

Thanks to Brian Kreeger and the Twin Cities R User Group for attending my presentation.

Thanks to Nick (last name?) for helpful suggestions that improved this presentation.