### start necessary libraries
# data import libraries
library(xlsx)
library(foreign)
library(rgdal)
library(tidyverse)
library(dplyr)
# reproducible research library
library(knitr)
# plotting and maps libraries
library(rmapshaper) # for simplifying maps
library(ggplot2)
library(leaflet)
library(ggmap)
### set figure save path to figure/
knitr::opts_chunk$set(fig.path = 'figure/')
knitr::opts_chunk$set(fig.width=12, fig.height=8)
Population data in Australia 2009 to 2014, grouped by Statistical Area Level 3 (SA3) from http://www.health.gov.au/internet/main/publishing.nsf/Content/PHN-Demographic_Data
Primary Health Network (‘PHN’) map data from http://www.health.gov.au/internet/main/publishing.nsf/content/phn-boundaries
Concordance table between PHN geographical area and Statistical Area Level 3 from http://www.health.gov.au/internet/main/publishing.nsf/Content/PHN-Concordances
General Practice (‘GP’, also known as family medicine) workforce by PHN found from Australian Government Health Workforce Data website (http://hwd.health.gov.au/), direct links for General Practitioner data by PHN is not available without login and setting search terms. Pre-downloaded 2016 data.
# download data files if necessary, and extract if necessary
# minimal processing to rename variables and remove variables not required
# Primary Health Network map boundaires
url.phnboundaries <- 'http://www.health.gov.au/internet/main/publishing.nsf/Content/20FD74ABB14A1297CA257F150001FD3B/$File/PHN_boundaries_AUS_May2017_V7_Shapefile.zip'
if (!file.exists('PHN_boundaries_AUS_May2017_V7.shp')) {
if (!file.exists('PHNboundaries.zip')) {
if (download.file(url.phnboundaries,'PHNboundaries.zip')) {
stop('Unable to download data file')
}
unzip('PHNboundaries.zip')
}
}
oz.phn.map <- readOGR('PHN_boundaries_AUS_May2017_V7.shp')
## OGR data source with driver: ESRI Shapefile
## Source: "PHN_boundaries_AUS_May2017_V7.shp", layer: "PHN_boundaries_AUS_May2017_V7"
## with 31 features
## It has 8 fields
## Integer64 fields read as strings: OBJECTID
# map data includes the list of PHNs in a DBF
oz.phn.description <- read.dbf('PHN_boundaries_AUS_May2017_V7.dbf')
# Populations, in Statistical Area 3 (SA3) areas
url.populations <- 'http://www.health.gov.au/internet/main/publishing.nsf/Content/AEADA0341B987748CA257F15000413F6/$File/PopulationReport.xlsx'
if (!file.exists('PopulationReport.xlsx')) {
if (download.file(url.populations,'PopulationReport.xlsx', method = 'curl')) {
# method 'curl' required for Windows
stop('Unable to download data file')
}
}
population.2014 <- as.tibble(read.xlsx('PopulationReport.xlsx', sheetName = 'Pop2014', startRow = 9, endRow = 359, header = FALSE))
# variable names needs to be added back into population table
names(population.2014) <- c('Region','Region2','Nothing','AllAges','Age0_4','Age5_9','Age10_14','Age15_19','Age20_24','Age25_29','Age30_34','Age35_39','Age40_44','Age45_49','Age50_54','Age55_59','Age60_64','Age65_69','Age70_74','Age75_79','Age80_84','Age85plus')
population.2014 <- population.2014 %>%
select(-Nothing,-Region) %>%
rename(SA3_NAME_2011 = Region2)
# the original 'Region' variable had leading spaces/tabs
url.concordance <- 'http://www.health.gov.au/internet/main/publishing.nsf/Content/4FAAB33C3ED3E520CA257F150001FD3A/$File/CG_SA3_2011_PHN_2015.xls'
# The correlation between Primary Health Network (PHN) zones and Statistical Area 3 (SA3) areas
# There may be multiple SA3s in a PHN, and a SA3 might span over the 'boundary' between PHNs
# this is the 2011 SA3 names, which is required for 2009 to 2014 population data
#
if (!file.exists('CGSA3_2011PHN2015.xlsx')) {
if (download.file(url.concordance,'CGSA3_2011PHN2015.xlsx', method = 'curl')) {
stop('Unable to download data file')
}
}
sa3.phn.concordance <- as.tibble(read.xlsx('CGSA3_2011PHN2015.xlsx',
sheetName = 'Table 3', startRow = 8, header = FALSE))
names(sa3.phn.concordance) <- c('SA3_CODE_2011','SA3_NAME_2011','PHN_CODE','PHN_NAME','RATIO','PERCENTAGE')
gp.numbers <- as.tibble(read.csv('table_2018-03-12_14-41-09.csv', skip = 11, row.names = NULL))
# number of general practitioners 'GP' in each primary health network (PHN) 2016
names(gp.numbers) <- c('PHN_NAME','gp','X') # rename columns
gp.numbers <- gp.numbers %>%
select(-X) # remove column not needed (and empty)
gp.numbers[gp.numbers$PHN_NAME == 'Central Queensland','PHN_NAME'] <-
'Central Queensland, Wide Bay, Sunshine Coast'
Places Population, General Practitioner numbers and Population per General practitioner information into map file
Creates a data frame with
# choose all ages statistic
select.age.population <- select(population.2014, SA3_NAME_2011, AllAges)
# calculate population in each PHN
phn.population <- sa3.phn.concordance %>%
merge(select.age.population, by = 'SA3_NAME_2011') %>%
# merge population numbers by SA3 areas
mutate(PHN_Number = as.numeric(AllAges)*as.numeric(RATIO)) %>%
# calculate population in each SA3 as proportion in each PHN
# some SA3 are spread across more than one PHN
group_by(PHN_NAME) %>%
# PHN can have multiple SA3
summarize(population = sum(PHN_Number))
# add GP information to each PHN
# calculate population per GP ratio in each PHN
combined.oz.phn.description <- oz.phn.description %>%
merge(gp.numbers, by = 'PHN_NAME') %>%
merge(phn.population, by = 'PHN_NAME') %>%
mutate(pop.gp.ratio = population/gp) %>%
# just select the variables that we need
select(PHN_NAME, gp, population, pop.gp.ratio)
oz.phn.map@data <- merge(oz.phn.map@data, combined.oz.phn.description, by = 'PHN_NAME')
‘Click’ on region to reveal Population and GP numbers
oz_loc <- geocode('Australia', source='dsk')
## Information from URL : http://www.datasciencetoolkit.org/maps/api/geocode/json?address=Australia&sensor=false
phn.map <- ms_simplify(oz.phn.map) %>% # reduce points to about 5% of original
leaflet() %>% # the map generator
addTiles() %>% # base map, usually OpenStreetMap
setView(lng = oz_loc$lon, lat = oz_loc$lat, zoom = 4) %>% # set view
addPolygons(color="#444444", weight=1, smoothFactor=0.5,
opacity=0.8, fillOpacity = 0.15,
popup = ~paste(PHN_NAME, '<br>Population :',
sprintf('%.0f',population),
'<br>GPs :', gp,
'<br>Population to GP :',
sprintf('%.0f',pop.gp.ratio)),
fillColor = ~colorQuantile("YlOrRd", pop.gp.ratio)(pop.gp.ratio),
highlightOptions =
highlightOptions(color='green',weight=2,bringToFront = TRUE))
phn.map
‘Click’ on region to reveal Population and GP numbers