<< Workshop Home

Mapping GPS Coordinates

Shapefiles are great because they are already geo-referenced and ready to be mapped. However, it’s often the case that our geographic data are not stored in shapefiles. For example, when we collect the GPS coordinates of facilities or homes, we usually store them in some type of spreadsheet (Access, Excel, CSV, etc.). Luckily, we only need a little more code to place GPS points on a map. This is achieved with the coordinates() function.

Importing Spreadsheet Data

#Load packages
library(rgdal) #loads the "sp" package along with it by default
library(prettymapr) #scale bar and north arrow
library(foreign) #has function to read a DBF file
# Read in the health facilities DBF spreadsheet
facilities_dbf <- read.dbf("zwe_health_facility_mohcw.dbf")
class(facilities_dbf)
## [1] "data.frame"

We see that facilities_dbf is a data frame, not a shapefile. If we try to plot it the same way we did with the shapefile, we will get an error. This is because we have not encoded the latitude and longitude variables as spatial data.

plot(facilities_dbf) #Error: this is a data frame, which can't be plotted without indicating lat and lon

Selecting a Subset of a Data Frame

Before we figure out how to plot, let’s see that we can select a subset of the data frame the same way we selected a subset of a shapefile.

# Select a subset of the data frame
RH <- subset(facilities_dbf, TYPEOFFACI == "Rural Hospital")
class(RH) # this is still a data frame
## [1] "data.frame"

Plotting using Longitude and Latitude

One way we could plot the data frame is by indicating the LONGITUDE and LATITUDE variables as x and y values. However, this will result in a plot that looks more like a graph than a map.

# Plot the data frame by specifying lat and long
plot(x = RH$LONGITUDE, y = RH$LATITUDE)

Converting a Data Frame to a Shapefile

A better way to map the points is by converting the data frame to a shapefile. We can do this using the coordinates() function. Once we do that, R will know to treat these data as spatial data.

# Define coordinates using the variables containing longitude and latitude
coordinates(RH) <- ~ LONGITUDE + LATITUDE #variable names

# Check the class
class(RH) # now this is a shapefile
## [1] "SpatialPointsDataFrame"
## attr(,"package")
## [1] "sp"

Now that we have a shapefile, we can more easily plot without specifying longitude and latitude every time.

# Import the provinces shapefile to map with it
provinces_shp <- readOGR("zwe_polbnda_adm1_250k_cso.shp")
## OGR data source with driver: ESRI Shapefile 
## Source: "zwe_polbnda_adm1_250k_cso.shp", layer: "zwe_polbnda_adm1_250k_cso"
## with 10 features
## It has 5 fields
# Plot
plot(provinces_shp, col = "grey93", border = "grey",
      main = "Zimbabwe Rural Hospitals")
plot(RH, add = T, col = "darkgreen", pch = 18, cex = 1.5)

# Add a legend
legend("bottomright", legend = "Rural Hospitals",
        pch = 18, col = "darkgreen",
        bty = "n", # turn off the legend border
        cex = 1, # font size
        pt.cex = 1.5) # increase the symbol size)

# Add scale bar and north arrow
addscalebar(pos="bottomleft", style = "ticks")
addnortharrow(pos = "topright", cols = c("white", "grey50"), scale = 0.4)

<< Workshop Home