I dette kodeeksempel bruger jeg en geokodningsfunktion, som findes på datascienceplus, til at geokode Google tendensdata vedrørende søgeintensitetsdata. Jeg sammenligner søgetendens efter bynavn for “Burger” og “Pizza” i Tyskland. Derefter visualiserer jeg resultaterne med varmekort. Hertil benytter jeg Leaflet-pakken i R.
Geokodning af inputdata ved hjælp af Open Street Map API
I nedenstående kodeeksempel implementerer jeg geokodningsfunktionen fra “datascienceplus” og anvender den ved hjælp af to DataFrames med Google Trends-data. DataFrames indeholder data i tabelform hentet fra Google Trends-tjenesten. Tjenesten omfatter søgeintensitetsresultater efter tyske bynavne for søgeudtrykkene “Burger” og “Pizza”.
# implementering af en geokodningsfunktion ved hjælp af JSON-baseret OSM-API
#install.packages("jsonlite")
library(jsonlite)
# dokumentation: http://wiki.openstreetmap.org/wiki/Nominatim
# kilde:
# 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)))
}
# læsning af inputdata (tabelformede csv-filer med Google Trends-data
setwd("C:/Users/Linnart/Desktop/Supply Chain Analytics/08 R coding/01__spatial visualization/Spatial food trends analysis")
# inputdata omfatter Googles søgeintensitet for burger og pizza i Tyskland
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)
# geokodning inputdata, dvs. anvendelse af geokodningsfunktionen
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.)
# første, geocode burgerbyer
for(i in 1:nrow(input_burger_map)){
# brug geokoderen til at geokode bynavn
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]}
# sov et sekund for at undgå at blive forbudt af OSM API
Sys.sleep(1)
}
# sekund, geokode pizza byer
for(i in 1:nrow(input_pizza_map)){
# brug geokoderen til at geokode bynavn
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]}
# sov et sekund for at undgå at blive forbudt af OSM API
Sys.sleep(1)
}
Efter at have geokodet bynavne i DataFrames renser jeg dataene for at undgå tomme poster og tomme rækker. Til det bruger jeg pakken “dplyr” i R:
# rensning af datarammer, så ingen NA-værdier er indeholdt
# brug "dplyr" -pakke til rengøring
library(dplyr)
# anvend "dplyr"-pakke til rengøring
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")
Varmekortlægning af geokodede data ved hjælp af Leaflet i R
Efter at have geokodet og renset Google Trends-søgeintensitetsresultaterne for de tyske byer anvender jeg Leaflet-pakken i R til at oprette et varmekort. Ved hjælp af addHeatmap()-funktionen visualiserer jeg den rumlige fordeling af søgeintensiten for burger og pizza:
# import af folder og folder.extras gør det muligt for mig at lave et varmekort
library(leaflet)
library(leaflet.extras)
library(magrittr)
# definer centrum af kortet
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))
# opretter et varmekort til burgerens søgeintensitet# opretter et varmekort til pizzaens søgeintensitet
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)
# opretter et varmekort til pizzaens søgeintensitet
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 i et 1x2 gitter; til det skal du bruge "mapview"-pakken i R
#install.packages("mapview")
library(mapview)
latticeview(viz_map_burger,viz_map_pizza)

Rumlig datavisualisering i R kan også udføres med andre pakker, såsom deckgl, ggmap, ggplot2 og webglobe. Du kan finde eksempler på kodning af disse pakker på min blog.

Industriingeniør som gerne beskæftiger sig med optimering, simulation og matematisk modellering i R, SQL, VBA og Python
Leave a Reply