class: large
This talk will introduce Geocomputation with R, a new book on using R to work with geographic data. It covers some of the key contents from the book and provide some examples of what is possible when geographic datasets are approached from a 'data science' perspective, that ensures reproducibility. I'll show how working with geographic data has become much easier and more user friendly over the years, and demonstrate the importance of geographic data for informing policy.
--
hamb_geo_talk = list( intro = "about me + geo* data", ecosystem = "prominent spatial packages", live_demo = "actions speak louder than words", evidence4policy = "ensuring impact" )
str(hamb_geo_talk)
options(htmltools.dir.version = FALSE) library(RefManageR) BibOptions(check.entries = FALSE, bib.style = "authoryear", cite.style = 'alphabetic', style = "markdown", first.inits = FALSE, hyperlink = FALSE, dashed = FALSE) my_bib = ReadBib("refs-geostat.bib", check = FALSE)
Jakub Nowosad: developer of GeoPAT + more. Lecturing 09:00 on Wednesday.
Jannes Muenchow, creator of RQGIS. Lecturing Weds 13:30 on GIS Bridges and Weds 15:30 on Spatial CV.
--
--
system("whoami")
--
.pull-left[ - Environmental geographer
Learned R for PhD on energy and transport
Now work at the University of Leeds (ITS and LIDA)
Working on Geocomputation with R
devtools::install_github("r-rust/gifski") system("youtube-dl https://youtu.be/CzxeJlgePV4 -o v.mp4") system("ffmpeg -i v.mp4 -t 00:00:03 -c copy out.mp4") system("ffmpeg -i out.mp4 frame%04d.png ") f = list.files(pattern = "frame") gifski::gifski(f, gif_file = "g.gif", width = 200, height = 200)
]
--
.pull-right[ Image credit: Jeroen Ooms + others
knitr::include_graphics("https://user-images.githubusercontent.com/1825120/39661313-534efd66-5047-11e8-8d99-a5597fe160ff.gif")
]
.pull-left[
]
--
.pull-right[
knitr::include_graphics("https://raw.githubusercontent.com/npct/pct-team/master/figures/Leeds-network.png")
Example: Propensity to Cycle Tool (PCT) in Manchester: http://pct.bike/m/?r=greater-manchester
]
--
knitr::include_graphics("https://media3.giphy.com/media/YkXNjAkG7CfEVx3gcy/giphy.gif?cid=3640f6095bd86a5e784739746ba086e4")
--
Geocomputation with R provides new tools
background-image: url("https://media1.giphy.com/media/Hw5LkPYy9yfVS/giphy.gif")
.pull-left[
GeoComputation is about using the various different types of geodata and about developing relevant geo-tools within the overall context of a 'scientific' approach
r Citep(my_bib, "openshaw_geocomputation_2000", .opts = list(cite.style = "authoryear"))
.
]
.pull-right[
knitr::include_graphics("http://www.ccg.leeds.ac.uk/people/s.openshaw/s.openshaw.png")
]
--
At the turn of the 21st Century it was unrealistic to expect readers to be able to reproduce code examples, due to barriers preventing access to the necessary hardware, software and data
r Citep(my_bib, "lovelace_geocomputation_2019", .opts = list(cite.style = "authoryear"))
--
What distinguishes geocomputation from the older quantitative geography, is its emphasis on "creative and experimental" GIS applications
r Citep(my_bib, "longley_geocomputation_1998", .opts = list(cite.style = "authoryear"))
.
--
It's about doing "practical work that is beneficial or useful" r Citep(my_bib, "openshaw_geocomputation_2000", .opts = list(cite.style = "authoryear"))
.
--
about harnessing the power of modern computers to do things with geographic data.
.pull-left[
Foundations
Extensions
Applications
]
.pull-right[
knitr::include_graphics("https://raw.githubusercontent.com/Robinlovelace/geocompr/master/images/frontcover.png")
]
class: inverse, center, middle
vignette("tidy-data")
):
- Each variable forms a column.
- Each observation forms a row.
- Each type of observational unit forms a table
background-image: url("https://pbs.twimg.com/media/CvzEQcfWIAAIs-N.jpg") background-size: cover
R's predecesor was S, which was itself inspired by lisp r Citep(my_bib, "chambers_extending_2016", .opts = list(cite.style = "authoryear"))
.
This is geographic analysis in S r Citep(my_bib, "rowlingson_splancs_1993", .opts = list(cite.style = "authoryear"))
:
pts <- spoints(scan('cavities')) uk() pointmap(pts,add=T) zoom() uk(add=T) pointmap(pts,add=T) poly<-getpoly()
Still works today, 25 years later:
library(splancs) #> Spatial Point Pattern Analysis Code in S-Plus #> Version 2 - Spatial and Space-Time analysis
# install.packages("splancs"); library(splancs) # example, interactive! (commented bits) data(bodmin) plot(bodmin$poly, asp=1, type="n") pointmap(as.points(bodmin), add=TRUE) # zoom() # pointmap(as.points(bodmin), add=TRUE)
R' is robust and future-proof
See a video of Roger Bivand's talk on the subject (live demo of R 0.49) + GitHub repo
Rs capabilities have evolved substantially since then!
"The core R engine was not designed specifically for the display and analysis
of maps, and the limited interactive facilities it offers have drawbacks in this
area" r Citep(my_bib, "bivand_applied_2013", .opts = list(cite.style = "authoryear"))
.
--
Five years later...
--
"An example showing R's flexibility and evolving geographic capabilities is leaflet
r Citep(my_bib, "R-leaflet", .opts = list(cite.style = "authoryear"))
,
a package for making interactive maps that has been extended by the R community, as we'll see in Chapter 9"
r Citep(my_bib, "lovelace_geocomputation_2018", .opts = list(cite.style = "authoryear"))
.
library(sf) library(spData) plot(nz)
--
library(tmap) tm_shape(nz) + tm_polygons("Median_income", palette = "RdYlBu")
install.packages("tidyverse")
The tidyverse now (mostly) works with spatial data.
This is thanks to sf, a recent package (first release in 2016) that implements the open standard data model simple features. Get sf with:
install.packages("sf")
Raster data is also supported, in the more mature package raster:
install.packages("raster")
For datasets...:
install.packages("spData") install.packages("rnaturalearth")
For more on this see: github.com/Robinlovelace/geocompr.
A package by Mark Padgham and others:
Padgham, M., Lovelace, R., Salmon, M., Rudis, B., 2017. osmdata. The Journal of Open Source Software 2. https://doi.org/10.21105/joss.00305
library(osmdata) hamburg = getbb("hamburg") parks = opq(bbox = hamburg) %>% add_osm_feature(key = "leisure", value = "park") %>% osmdata_sf() parks
--
library(tmap) ttm() qtm(parks$osm_polygons)
class: inverse, center, middle
Collaboration is most important aspect of science (and reprex the most important R package!) (Jakub Nowosad, 2018, GEOSTAT)
Slides: https://geocompr.github.io/presentations/
Source code: https://github.com/geocompr/geostats_18
reprex::reprex(2 + 2)
2 + 2 #> [1] 4
Created on 2018-10-30 by the reprex package (v0.2.1)
Attaching packages
library(sf) library(raster)
library(tidyverse)
library(sf) f = system.file(package = "spData", "shapes/world.shp") world_sf = read_sf(f)
write_sf()/st_write()
writes data st_write(prague_sf, 'data/prague_sf.gpkg')
. See supported formats with: sf::st_drivers()
. Details: Chapter 6 of our book: geocompr.robinlovelace.net/read-write.html
library(spData) # we'll use our own data class(world) world
# --- ## Structure of the sf objects # world$name_long # ``` # # ```r # world$name_long[1:3] # ``` # # ```r # world$geom # ``` # # ```r # print(world$geom, n = 3)
world %>% filter(name_long == "United Kingdom")
--
Base R equivalent:
world[world$name_long == "United Kingdom", ]
--
Question:
identical( world %>% filter(name_long == "United Kingdom"), world[world$name_long == "United Kingdom", ] ) # ?
world_cont = world %>% group_by(continent) %>% summarize(pop_sum = sum(pop, na.rm = TRUE))
print(world_cont, n = 1)
st_set_geometry
function can be used to remove the geometry column:world_df = st_set_geometry(world_cont, NULL) class(world_df)
It's a big topic which includes:
See Chapter 4 of Geocomputation with R
lnd_buff = lnd[1, ] %>% st_transform(crs = 27700) %>% # uk CRS st_buffer(500000) %>% st_transform(crs = 4326) near_lnd = world[lnd_buff, ] plot(near_lnd$geom)
Some objects have multiple geometries:
st_geometry_type(near_lnd)
Which have more than 1?
data.frame(near_lnd$name_long, sapply(near_lnd$geom, length))
near_lnd_new = world %>% st_cast(to = "POLYGON") %>% filter(st_intersects(., lnd_buff, sparse = FALSE)) plot(st_geometry(near_lnd_new))
na_2163 = world %>% filter(continent == "North America") %>% st_transform(2163) #US National Atlas Equal Area st_crs(na_2163)
na = world %>% filter(continent == "North America") png('slides/figs/coord_compare.png', width = 1000, height = 250) par(mfrow = c(1, 2), mar=c(0,0,0,0)) plot(na[0]);plot(na_2163[0]) dev.off()
sf
objects can be quickly created using the plot()
function:plot(world[0])
plot(world["pop"])
png('slides/figs/plot_compare.png', width = 800, height = 300) par(mfrow = c(1, 2), mar=c(0,0,1,0)) plot(world[0]);plot(world["pop"]) dev.off()
https://cran.r-project.org/web/packages/tmap/vignettes/tmap-nutshell.html
library(tmap) tmap_mode("plot") #check the "view" tm_shape(world, projection = "+proj=moll") + tm_polygons("lifeExp", title = "Life expactancy", style = "pretty", palette = "RdYlGn") + tm_style("grey")
library(leaflet) leaflet(world) %>% addTiles() %>% addPolygons(color = "#444444", weight = 1, fillOpacity = 0.5, fillColor = ~colorQuantile("YlOrRd", lifeExp)(lifeExp), popup = paste(round(world$lifeExp, 2)))
library(widgetframe) library('leaflet') l = leaflet(world) %>% addTiles() %>% addPolygons(color = "#444444", weight = 1, fillOpacity = 0.5, fillColor = ~colorQuantile("YlOrRd", lifeExp)(lifeExp), popup = paste(round(world$lifeExp, 2))) frameWidget(l, height = '400')
Raster data in R is evolving:
Spatial*
form using as(my_vector, "Spatial")
before working on raster-vector interactionsclass: inverse, center, middle
background-image: url(https://pbs.twimg.com/media/DOH94nXUIAAgcll.jpg) background-position: 50% 50% class: center, bottom, inverse
.pull-left[
knitr::include_graphics("https://raw.githubusercontent.com/Robinlovelace/erum18-transport/master/transport-projections-ipcc.png")
]
--
.pull-right[
People like to travel!
Does not 'saturate' with income
Hard to decarbonise via technology
]
A few examples:
--
--
--
--
--
Challenge: balance between innovation and tool overload
Challenge: balance between transparency/simplicity and sophistication of analysis
That is a balance R is ideally set-up to strike
class: center, middle
Reproducible slides + app: github.com/Robinlovelace/erum18-transport
Transport chapter in Geocomputation with R (feedback welcome): geocompr.robinlovelace.net
Slides created via the R package xaringan.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.