Wärmekarten mit Leaflet

In diesem Codebeispiel verwende ich eine Geokodierungsfunktion von datascienceplus um die Suchintensität von Google-Trends zu geokodieren und den Suchtrend nach Städtenamen für “Burger” und “Pizza” in Deutschland zu vergleichen. Anschließend visualisiere ich die Ergebnisse mit Wärmekarten. Diese erstelle ich mit dem Leaflet-Paket in R.

Geokodierung von Eingabedaten mithilfe der Open Street Map API

Im folgenden Codierungsbeispiel implementiere ich die Geokodierungsfunktion aus “datascienceplus” und wende sie mit zwei DataFrames mit Google Trends-Daten an. Die DataFrames enthalten tabellarische Daten, die vom Google Trends-Dienst abgerufen wurden. Dazu gehören Suchintensitätswerte nach deutschen Städtenamen für die Suchbegriffe “Burger” und “Pizza”.

# Implementierung einer Geokodierungsfunktion mithilfe der JSON-basierten OSM-API
#install.packages("jsonlite")
library(jsonlite)

# Dokumentation: http://wiki.openstreetmap.org/wiki/Nominatim
# Quelle: 
# 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)))
}

# Lesen von Eingabedaten (tabellarische CSV-Dateien mit Google Trends-Daten
setwd("C:/Users/Linnart/Desktop/Supply Chain Analytics/08 R coding/01__spatial visualization/Spatial food trends analysis")

# Eingabedaten umfassen die Google-Suchintensität für Burger und Pizza in Deutschland
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)

# Geokodierung von Eingabedaten, d. h. Anwenden der Geokodierungsfunktion
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.)

# zuerst Geocode-Burger-Städte
for(i in 1:nrow(input_burger_map)){
  # verwende den Geocoder, um den Namen der Stadt zu geocodieren
  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]}
  # eine Sekunde schlafen, um nicht von der OSM-API gebannt zu werden
  Sys.sleep(1)
}

# zweitens Geocode-Pizzastädte
for(i in 1:nrow(input_pizza_map)){
  # Verwende den Geocoder, um den Namen der Stadt zu geocodieren
  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]}
  # eine Sekunde schlafen, um nicht von der OSM-API gebannt zu werden
  Sys.sleep(1)
}

Nachdem ich die Städtenamen in den DataFrames geokodiert habe bereinige ich die Daten um leere Einträge und leere Zeilen zu vermeiden. Dafür benutze ich das “dplyr” -Paket in R:

# Datenrahmen so bereinigen, dass keine NA-Werte enthalten sind
# Verwende zum Reinigen das Paket "dplyr"
library(dplyr)

# Verwende das "dplyr" -Paket zur Reinigung an
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")

Geokodierte Heatmapping-Daten mithilfe von Leaflet

Nachdem ich die Suchintensitätswerte von Google Trends nach deutschen Top-Städten geokodiert und bereinigt habe verwende ich das Leaflet-Paket in R um eine Heatmap zu erstellen. Mit der Heatmap visualisiere ich die räumliche Verteilung der Suchintensität von Suchbegriffen:

# Durch den Import von leaflet und leaflet.extras kann ich eine Heatmap erstellen
library(leaflet)
library(leaflet.extras)
library(magrittr)

# Kartenmitte definieren
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)) 

# Erstellen einer Heatmap für die Intensität der Burger-Suche
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)

# Erstellen einer Heatmap für die Intensität der Pizzasuche
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 in ein 1x2-Raster; verwende dazu das Paket "mapview" in R.
#install.packages("mapview")
library(mapview)
latticeview(viz_map_burger,viz_map_pizza)

Die Visualisierung räumlicher Daten in R kann auch mit anderen Paketen wie Deckgl, GGMAP, GGPLOT2 und Webglobe realisiert werden. Codierungsbeispiele zu diesen Paketen finden Sie auch auf meinem Blog.

You May Also Like

Leave a Reply

Leave a Reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.