class: large

What is this talk about?

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)

intro


'Team geocompr'

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)

--

--


whoami

system("whoami")

--

.pull-left[ - Environmental geographer

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[

Why geo*?

Geographic data is everywhere

underlies some of society's biggest issues

global analyses given local meaning

]

--

.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

]


R can help tackle Big issues

--

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")

Geocomputation with R


What is Geocomputation?

.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"))


Other aspects of the definition

--

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.


What's in the geocompr box?

.pull-left[

Foundations

Extensions

Applications

]

.pull-right[

knitr::include_graphics("https://raw.githubusercontent.com/Robinlovelace/geocompr/master/images/frontcover.png")

]


class: inverse, center, middle

ecosystem


Context

  • 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


Enter sf


A brief history of geographic data in R

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

Live demo (try this)!

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

Observations


A brief history of geographic data viz in R

"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")).


Base R graphics: sf

library(sf)
library(spData)
plot(nz)

--

tmap

library(tmap)
tm_shape(nz) +
  tm_polygons("Median_income", palette = "RdYlBu")

Summary: recent packages for spatial data

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.


osmdata

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

--

A map can tell 1000 words

library(tmap)
ttm()
qtm(parks$osm_polygons)

class: inverse, center, middle

Demo: sf in the tidyverse


Reproducibility + collaboration

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)

Issue: Conflicting function names

library(tidyverse)

Reading and writing spatial data

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


Structure of the sf objects

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)

Attribute operations: filtering

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", ]
) # ?

Aggregation

world_cont = world %>% 
        group_by(continent) %>% 
        summarize(pop_sum = sum(pop, na.rm = TRUE))
print(world_cont, n = 1)
world_df = st_set_geometry(world_cont, NULL)
class(world_df)

Spatial operations

It's a big topic which includes:

See Chapter 4 of Geocomputation with R


Spatial subsetting

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)

Multi-objects

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))

Subsetting contiguous polygons

near_lnd_new = world %>% 
  st_cast(to = "POLYGON") %>% 
  filter(st_intersects(., lnd_buff, sparse = FALSE))
plot(st_geometry(near_lnd_new))

CRS: a key geo* concept

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()


Making maps

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()


tmap

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")

leaflet

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')

What about raster data?

Raster data in R is evolving:


class: inverse, center, middle

Applications: R for sustainable transport research


background-image: url(https://pbs.twimg.com/media/DOH94nXUIAAgcll.jpg) background-position: 50% 50% class: center, bottom, inverse

Case study: congested cities


Transport: growing source of emissions

.pull-left[

knitr::include_graphics("https://raw.githubusercontent.com/Robinlovelace/erum18-transport/master/transport-projections-ipcc.png")

]

--

.pull-right[

]


'Leverage points' where R skills can help

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

Thanks, links, happy R day travels 🚶, 🚲 + 🚀!

Slides created via the R package xaringan.



geocompr/geocompkg documentation built on July 5, 2025, 2:35 a.m.