Repository navigation
Expand file tree
/
Copy pathREADME.Rmd
More file actions
247 lines (189 loc) · 7.14 KB
/
Copy pathREADME.Rmd
File metadata and controls
247 lines (189 loc) · 7.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
out.width = "100%",
fig.path = "man/figures/"
)
```
```{r, echo = FALSE, eval=FALSE}
library(sysfonts)
library(hexSticker)
library(showtext)
background_image <- file.path("man", "figures", "hex-bg.png")
font_name <- "Comfortaa"
sysfonts::font_add_google(font_name, db_cache = FALSE)
showtext::showtext_auto()
hexSticker::sticker(
background_image,
package = "wardboundaries",
p_size = 6, # font size
p_color = "white", # font colour,
p_family = font_name,
p_fontface = "bold",
p_x = 1, # package name position
p_y = 1, # package name position
s_x = 1, # background image position
s_y = 1, # background image position
s_width = 1, # background image width (1 = 100%)
h_size = 0, # get rid of the hex border
white_around_sticker = TRUE,
filename = file.path("man", "figures", "logo.png")
)
```
# wardboundaries
<!-- badges: start -->
[](https://www.repostatus.org/#wip)
<!-- badges: end -->
## Overview
**wardboundaries** is an R data package for mapping UK ward boundaries.
The main objects in the package are [sf](https://r-spatial.github.io/sf/) tibbles of ward boundaries, obtained from the ONS Open Geography Portal.
- All the original variables and observations are retained and a `geometry` column of type MULTIPOLYGON has been added
- LAD codes and names have been added to datasets where required, as I believe they will prove useful in most use cases
The data is ready to be joined to measurements and plotted with e.g. `ggplot2` or `leaflet`.
### Current datasets
**20m resolution**
- countries_dec2022_20m
- lad_dec2022_20m
- lad_may2023_20m
- lad_dec2023_20m
- wards_dec2022_20m
- wards_may2023_20m
- wards_dec2023_20m
**200m resolution**
- wards_dec2011
- wards_dec2019
- wards_dec2020
- wards_dec2021
- wards_dec2022
- wards_may2023
- wards_dec2023
**500m resolution**
- countries_dec2022
- lad_dec2022
- lad_may2023
## Installation
``` r
devtools::install_github("jimgar/wardboundaries")
```
## Use and examples
### Access
Accessing a dataset can be done two ways.
By namespace, without loading the whole library
``` {r}
wardboundaries::wards_dec2022
```
Or by loading the whole library
``` {r}
library(wardboundaries)
wards_dec2022
```
### Map with ggplot2
Perhaps you have some sort of demographic data for each ward. Plotting this as a choropleth with ggplot2 is nice and straightforward
``` {r}
# Make some random numbers that represent a demographic dataset
demo_data <- tibble::tibble(
WD22CD = dplyr::pull(wardboundaries::wards_dec2022, WD22CD),
number_of_ducks = sample(
150:1500, nrow(wardboundaries::wards_dec2022),
replace = TRUE
)
)
demo_data
```
``` {r, warning = FALSE}
# Join the datasets together
ducks_per_ward <- dplyr::left_join(
wardboundaries::wards_dec2022,
demo_data,
by = dplyr::join_by(WD22CD)
)
```
``` {r}
# Plot
ducks_per_ward |>
ggplot2::ggplot() +
ggplot2::geom_sf(ggplot2::aes(fill = number_of_ducks), colour = NA) +
ggplot2::theme_void()
```
The following plot isn't exactly pretty, but it shows how easy it is to focus
in on a particular local authority and add labels
``` {r, warning = FALSE}
# Plot
ducks_per_ward |>
dplyr::filter(LAD22NM == "Vale of White Horse") |>
ggplot2::ggplot() +
ggplot2::geom_sf(
ggplot2::aes(fill = number_of_ducks),
colour = NA,
show.legend = FALSE
) +
ggplot2::geom_sf_label(ggplot2::aes(label = number_of_ducks)) +
ggplot2::theme_void()
```
### Map with leaflet
The following example is mainly cribbed from [Leaflet for R](https://rstudio.github.io/leaflet/choropleths.html). With a couple of format
helpers and not much code, it's possible to create an interactive version of
the map
```{r, eval = FALSE}
# Format helpers
pal <- leaflet::colorNumeric("Greens", domain = ducks_per_ward$number_of_ducks)
thousands <- scales::label_comma()
labels <- sprintf(
"<strong>%s</strong><br/>%s",
ducks_per_ward$WD22NM, thousands(ducks_per_ward$number_of_ducks)
) |> lapply(htmltools::HTML)
# Leaflet map
leaflet::leaflet() |>
leaflet::addTiles() |>
leaflet::addPolygons(
data = ducks_per_ward,
fillColor = ~ pal(number_of_ducks),
weight = 0.1,
opacity = 0.9,
color = "white",
dashArray = "3",
fillOpacity = 0.9,
highlightOptions = leaflet::highlightOptions(
weight = 1,
color = "yellow",
dashArray = "",
fillOpacity = 0.9,
bringToFront = TRUE
),
label = labels,
labelOptions = leaflet::labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "15px",
direction = "auto"
)
) |>
leaflet::addLegend(
pal = pal,
values = ducks_per_ward$number_of_ducks,
opacity = 0.9,
title = NULL,
position = "topleft"
)
```
```{r, echo = FALSE, fig.align = "centre"}
knitr::include_graphics("man/figures/leaflet.gif")
```
## Further resources
### geographr
If your needs are suited to my example maps above then **wardboundaries** works just fine.
If you have more complex requirements then I recommend checking out [geographr](https://github.com/humaniverse/geographr). They go far beyond the simple local authority / ward scenario and have boundaries for larger hierarchies, lookup tables, NHS point data, etc. Each dataset in **geographr** is slimmed down to the essential variables, so you may have to stitch different datasets together. Another important note is that the polygons are highly simplified, whereas **wardboundaries** offers up to 20m resolution.
### Trafford lab API post
A couple of weeks before making this package I knew next to nothing about geospatial data or how to get hold of it. I still don't, but Trafford Council's Data lab wrote a very helpful [Medium post](https://medium.com/@traffordDataLab/pushing-the-boundaries-with-the-open-geography-portal-api-4d70637bddc3) that explains how to work with the ONS Open Geography Portal's API to get data in practice. If you have a niche interest this resource will help you understand how to create a specific query for your needs and read the data straight into R with `sf`.
### R map books
- [Spatial Data Science (with applications in R)](https://r-spatial.org/book/) "introduces and explains the concepts underlying spatial data: points, lines, polygons, rasters, coverages, geometry attributes, data cubes, reference systems, as well as higher-level concepts including how attributes relate to geometries and how this affects analysis"
- [Geocomputation with R](https://geocompr.robinlovelace.net/index.html) "is for people who want to analyze, visualize and model geographic data with open source software"
## Credits
Developed by [Jim Gardner](https://github.com/jimgar).
Hex image cropped from [Invocation 6](https://helveticablanc.com/20220331-invocation-6.html) by Helvetica Blanc.
Largely modelled on and inspired by [geographr](https://github.com/humaniverse/geographr).
See [LICENCE](/LICENSE)