Introdução aos mapas de calor: Leaflet em R

Neste exemplo de código, uso uma função de geocodificação encontrada no datascienceplus para geocodificar os dados de intensidade de pesquisa de tendências do Google, comparando a tendência de pesquisa por nome de cidade para “Burger” e “Pizza” na Alemanha. Em seguida, visualizo os resultados com mapas de calor, gerados com o pacote Leaflet no R.

Dados de entrada de geocodificação usando Open Street Map

No exemplo de codificação abaixo, implemento a função de geocodificação de “datascienceplus” e a aplico usando dois DataFrames com dados do Google Trends. Os DataFrames contêm dados tabulares recuperados do serviço Google Trends, compreendendo pontuações de intensidade de pesquisa por nomes de cidades alemãs para os termos de pesquisa “Burger” e “Pizza”.

# implementing a geocoding function, using JSON-based OSM-API
#install.packages("jsonlite")
library(jsonlite)

# documentation: http://wiki.openstreetmap.org/wiki/Nominatim
# source: 
# datascienceplus.com/osm-nominatim-with-r-getting-locations-geo-coordinates-by-its-address/
osm_geocoder <- function(address = NULL)
{
  if(suppressWarnings(is.null(address)))
    return(data.frame())
  
  tryCatch(
    d <- jsonlite::fromJSON( 
      gsub('\\@addr\\@', gsub('\\s+', '\\%20', address), 
           'http://nominatim.openstreetmap.org/search/@addr@?format=json&addressdetails=0&limit=1')
    ), error = function(c) return(data.frame())
  )

  if(length(d) == 0) 
    return(data.frame())
  
  return(data.frame(lon = as.numeric(d$lon), lat = as.numeric(d$lat)))
}

# reading input data (tabular csv files with Google Trends data 
setwd("C:/Users/Linnart/Desktop/Supply Chain Analytics/08 R coding/01__spatial visualization/Spatial food trends analysis")

# input data comprises Google search intensity for burger and pizza in Germany
input_pizza_map <- read.csv(file="Pizza on map.csv",header=TRUE,sep=",",stringsAsFactors = FALSE)
input_burger_map <- read.csv(file="Burger on map.csv",header=TRUE,sep=",",stringsAsFactors = FALSE)
#input_burger_and_pizza_map <-read.csv(file="Pizza vs Burger on map.csv",header=TRUE,sep=",",stringsAsFactors = FALSE)
#input_burger_and_pizza_timeline <- read.csv(file="Pizza vs Burger.csv",header=TRUE,sep=",",stringsAsFactors = FALSE)

# geocoding input data, i.e. applying the geo-coding function
input_pizza_map<-data.frame(input_pizza_map$Town.City,"Lat"=rep(NA,nrow(input_pizza_map)),"Long"=rep(NA,nrow(input_pizza_map)),input_pizza_map$Pizza...2.12.17...2.12.18.)
input_burger_map<-data.frame(input_burger_map$Town.City,"Lat"=rep(NA,nrow(input_burger_map)),"Long"=rep(NA,nrow(input_burger_map)),input_burger_map$Burger...2.12.17...2.12.18.)

# first, geocode burger cities
for(i in 1:nrow(input_burger_map)){
  # use the geocoder to geocode city name
  geocodes <- osm_geocoder(address=paste0(input_burger_map$input_burger_map.Town.City[i],", Germany"))
  print(input_burger_map$input_burger_map.Town.City[i])
  if(nrow(geocodes)>=1){
    input_burger_map$Lat[i] <- geocodes$lat[1]
    input_burger_map$Long[i]<- geocodes$lon[1]}
  # sleep one second to avoid getting banned by OSM API
  Sys.sleep(1)
}

# second, geocode pizza cities
for(i in 1:nrow(input_pizza_map)){
  # use the geocoder to geocode city name
  geocodes <- osm_geocoder(address=paste0(input_pizza_map$input_pizza_map.Town.City[i],", Germany"))
  print(input_pizza_map$input_pizza_map.Town.City[i])
  if(nrow(geocodes)>=1){
    input_pizza_map$Lat[i] <- geocodes$lat[1]
    input_pizza_map$Long[i]<- geocodes$lon[1]}
  # sleep one second to avoid getting banned by OSM API
  Sys.sleep(1)
}

Depois de geocodificar os nomes das cidades nos DataFrames, limpo os dados para evitar entradas e linhas vazias. Para isso utilizo o pacote “dplyr” no R:

# cleaning data frames so that no NA values are contained
# use "dplyr" package for cleaning 
library(dplyr)

# apply "dplyr" package for cleaning
cleaned_pizza_map <- input_pizza_map %>% filter(!is.na(Lat)) 
colnames(cleaned_pizza_map)<-c("City","Lat","Long","Trend")
cleaned_burger_map <- input_burger_map %>% filter(!is.na(Lat))
colnames(cleaned_burger_map)<-c("City","Lat","Long","Trend")

Dados geocodificados de mapeamento de calor, usando o Leaflet

Depois de geocodificar e limpar as pontuações de intensidade de pesquisa do Google Trends pelas principais cidades alemãs, uso o pacote Leaflet em R para criar um mapa de calor. Usando o mapa de calor, visualizo a distribuição espacial da intensidade de pesquisa do termo de pesquisa:

# importing leaflet and leaflet.extras will enable me to make a heatmap
library(leaflet)
library(leaflet.extras)
library(magrittr)

# define center of map
lat_center <- c(cleaned_burger_map$Lat,cleaned_pizza_map$Lat) %>% as.numeric() %>% mean
long_center <- mean(c(cleaned_burger_map$Long,cleaned_pizza_map$Long)) 

# creating a heat map for the burger search intensity 
viz_map_burger <- cleaned_burger_map %>%
  leaflet() %>% 
  addTiles() %>% 
  addProviderTiles(providers$OpenStreetMap.DE) %>% 
  setView(long_center,lat_center,6) %>%
  addHeatmap(lng=~Long,lat=~Lat,intensity=~Trend,max=100,radius=20,blur=10)

# creating a heat map for the pizza search intensity 
viz_map_pizza <- cleaned_pizza_map %>%
  leaflet() %>% 
  addTiles() %>% 
  addProviderTiles(providers$OpenStreetMap.DE) %>% 
  setView(long_center,lat_center,6) %>%
  addHeatmap(lng=~Long,lat=~Lat,intensity=~Trend,max=100,radius=20,blur=10)

# plot into a 1x2 grid; for that use the "mapview" package in R
#install.packages("mapview")
library(mapview)
latticeview(viz_map_burger,viz_map_pizza)

A visualização de dados espaciais em R também pode ser feita com outros pacotes, como deckgl, ggmap, ggplot2 e webglobe. Você pode encontrar exemplos de codificação relacionados a esses pacotes no meu blog.

You May Also Like

Leave a Reply

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.