library(knitr) knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
The absmaps
package exists to make it easier to download, compress and convert ABS shapefile data to sf
objects to be used in R.
You can install absmaps
from github with:
# install.packages("devtools") devtools::install_github("wfmackey/absmaps")
Additionally, the sf
package is required to handle the sf
objects:
install.packages("sf") library(sf)
And we will use the tidyverse
packages in this example:
library(tidyverse)
Available maps are listed below. These will be added to over time. If you would like to request a map to be added, let me know via an issue on this Github repo. (Or send me an email: wfmackey@gmail.com)
More details about ASGS structrues can be found on the ABS website.
sa1
, year = 2011
sa1
, year = 2016
sa2
, year = 2011
sa2
, year = 2016
sa3
, year = 2011
sa3
, year = 2016
sa4
, year = 2011
sa4
, year = 2016
gcc
, year = 2011
gcc
, year = 2016
state
, year = 2011
state
, year = 2016
ra
, year = 2011
ra
, year = 2016
mesh_nsw
, year = 2011
mesh_nsw
, year = 2016
mesh_vic
, year = 2011
mesh_vic
, year = 2016
mesh_qld
, year = 2011
mesh_qld
, year = 2016
mesh_sa
, year = 2011
mesh_sa
, year = 2016
mesh_wa
, year = 2011
mesh_wa
, year = 2016
mesh_tas
, year = 2011
mesh_tas
, year = 2016
mesh_nt
, year = 2011
mesh_nt
, year = 2016
mesh_act
, year = 2011
mesh_act
, year = 2016
mesh_other
, year = 2011
mesh_other
, year = 2016
indigenous_locations
, year = 2011
indigenous_locations
, year = 2016
indigenous_area
, year = 2011
indigenous_area
, year = 2016
indigenous_regions
, year = 2011
indigenous_regions
, year = 2016
ced
, year = 2018
sed
, year = 2018
lga
, year = 2016
lga
, year = 2018
The absmaps
package uses the load_absmaps
to download and load a particular geospatial object:
library(absmaps) mapdata1 <- load_absmaps(area = "sa3", year = 2011) glimpse(mapdata1) #> Observations: 351 #> Variables: 12 #> $ sa3_code_2011 <chr> "10101", "10102", "10103", "10104", "10201", "10… #> $ sa3_name_2011 <chr> "Goulburn - Yass", "Queanbeyan", "Snowy Mountain… #> $ sa4_code_2011 <chr> "101", "101", "101", "101", "102", "102", "103",… #> $ sa4_name_2011 <chr> "Capital Region", "Capital Region", "Capital Reg… #> $ gcc_code_2011 <chr> "1RNSW", "1RNSW", "1RNSW", "1RNSW", "1GSYD", "1G… #> $ gcc_name_2011 <chr> "Rest of NSW", "Rest of NSW", "Rest of NSW", "Re… #> $ state_code_2011 <chr> "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"… #> $ state_name_2011 <chr> "New South Wales", "New South Wales", "New South… #> $ albers_sqkm <dbl> 21236.6140, 6511.1214, 14281.8301, 9864.9397, 98… #> $ cent_lat <dbl> 149.0763, 149.6013, 148.9416, 149.8063, 151.2182… #> $ cent_long <dbl> -34.55399, -35.44940, -36.43958, -36.49934, -33.… #> $ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((149.1198 -3..., MUL…
Or
mapdata2 <- load_absmaps(area = "sa2", year = 2016) glimpse(mapdata2) #> Observations: 2,310 #> Variables: 15 #> $ sa2_main_2016 <chr> "101021007", "101021008", "101021009", "10102101… #> $ sa2_5dig_2016 <chr> "11007", "11008", "11009", "11010", "11011", "11… #> $ sa2_name_2016 <chr> "Braidwood", "Karabar", "Queanbeyan", "Queanbeya… #> $ sa3_code_2016 <chr> "10102", "10102", "10102", "10102", "10102", "10… #> $ sa3_name_2016 <chr> "Queanbeyan", "Queanbeyan", "Queanbeyan", "Quean… #> $ sa4_code_2016 <chr> "101", "101", "101", "101", "101", "101", "101",… #> $ sa4_name_2016 <chr> "Capital Region", "Capital Region", "Capital Reg… #> $ gcc_code_2016 <chr> "1RNSW", "1RNSW", "1RNSW", "1RNSW", "1RNSW", "1R… #> $ gcc_name_2016 <chr> "Rest of NSW", "Rest of NSW", "Rest of NSW", "Re… #> $ state_code_2016 <chr> "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"… #> $ state_name_2016 <chr> "New South Wales", "New South Wales", "New South… #> $ areasqkm_2016 <dbl> 3418.3525, 6.9825, 4.7634, 13.0034, 3054.4099, 1… #> $ cent_lat <dbl> 149.7932, 149.2328, 149.2255, 149.2524, 149.3911… #> $ cent_long <dbl> -35.45508, -35.37590, -35.35103, -35.35520, -35.… #> $ geometry <MULTIPOLYGON [°]> MULTIPOLYGON (((149.7606 -3..., MUL…
The resulting sf
object contains one observation per area (in the
following examples, one observation per sa3
). It stores the geometry
information in the geometry
variable, which is a nested list
describing the area’s polygon. The object can be joined to a standard
data.frame
or tibble
and can be used with dplyr
functions.
sf
objectWe do all this so we can create gorgeous maps. And with the sf
object
in hand, plotting a map via ggplot
and geom_sf
is simple.
map <- sa32016 %>% filter(gcc_name_2016 == "Greater Melbourne") %>% # let's just look Melbourne ggplot() + geom_sf(aes(geometry = geometry)) # use the geometry variable map
include_graphics("VIGNETTE-1.png")
The data also include centorids of each area, and we can add these
points to the map with the cent_lat
and cent_long
variables using
geom_point
.
map <- sa32016 %>% filter(gcc_name_2016 == "Greater Melbourne") %>% # let's just look Melbourne ggplot() + geom_sf(aes(geometry = geometry)) + # use the geometry variable geom_point(aes(cent_lat, cent_long)) # use the centroid lat and longs map
include_graphics("VIGNETTE-2.png")
Cool. But, sidenote, this all looks a bit ugly. We can pretty it up
using ggplot
tweaks. See the comments on each line for its objective.
Also note that we’re filling the areas by their areasqkm
size, another
variable included in the sf
object (we’ll replace this with more
interesting data in the next section).
map <- sa32016 %>% filter(gcc_name_2016 == "Greater Melbourne") %>% # let's just look Melbourne ggplot() + geom_sf(aes(geometry = geometry, # use the geometry variable fill = areasqkm_2016), # fill by area size lwd = 0, # remove borders show.legend = FALSE) + # remove legend geom_point(aes(cent_lat, cent_long), # use the centroid lat and longs colour = "white") + # make the points white theme_void() + # clears other plot elements coord_sf(datum = NA) # fixes a gridline bug in theme_void() map
include_graphics("VIGNETTE-3.png")
At some point, we’ll want to join our spatial data with data-of-interest. The variables in our mapping data—stating the numeric code and name of each area and parent area—will make this relatively easy.
For example: suppose we had a simple dataset of median income by SA3 over time.
# Read data in some data income <- read_csv("data/median_income_sa3.csv") #> Parsed with column specification: #> cols( #> sa3_name_2016 = col_character(), #> year = col_character(), #> median_income = col_double() #> )
This income data contains a variable sa3_name_2016
, and we can use
dplyr::left_join()
to combine with our mapping data.
combined_data <- left_join(income, sa32016, by = "sa3_name_2016")
Now that we have a tidy dataset with 1) the income data we want to plot, and 2) the geometry of the areas, we can plot income by area:
map <- combined_data %>% filter(gcc_name_2016 == "Greater Melbourne") %>% # let's just look Melbourne ggplot() + geom_sf(aes(geometry = geometry, # use the geometry variable fill = median_income), # fill by unemployment rate lwd = 0) + # remove borders theme_void() + # clears other plot elements coord_sf(datum = NA) + # fixes a gridline bug in theme_void() labs(fill = "Median income") map
include_graphics("VIGNETTE-4.png")
The motivation for this package is that maps are cool and fun and are,
sometimes, the best way to communicate data. And making maps is R
with
ggplot
is relatively easy when you have the right object
.
Getting the right object
is not technically difficult, but requires
research into the best-thing-to-do at each of the following steps:
R
using one-of-many import tools.For me, at least, finding the correct information and developing the
best set of steps was a little bit interesting but mostly tedious and
annoying. The absmaps
package holds this data for you, so you can
spend more time making maps, and less time on Stack Overflow, the ABS
website, and lovely-people’s wonderful
blogs.
The absmaps
package uses four key functions to do-the-things-it-does:
utils::download.file
to download shapefile data from the ABS.sf::st_read
to read the shapefile into an sf
object.rmapshaper::ms_simplify
to nicely compress the sf
object.readr::write_rds
to write, and readr::read_rds
to read our nice sf
objects.There are a bunch of other fiddley-things on top of that, but those four steps are the 'workhorse' functions. A big thanks to people who built them.
If you're interested, check out load_absmaps.R
code in the R/
file. And, of course, if you have a suggestion to improve, please do let me know via an issue at https://github.com/wfmackey/absmaps.
Fair enough! The best avenue is via a Github issue at (wfmackey/absmaps). This is also the best place to request data that isn’t yet available in the package. You can also email me at wfmackey@gmail.com.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.