Learn R Programming

⚠️There's a newer version (0.6.0) of this package.Take me there.

spbabel: a tidy view of Spatial

Spbabel provides simple tools to flip between Spatial and tidy forms of data. This package aims assist in the ongoing development of tools for spatial data in R. There is limited use for users directly, though see examples below.

Installation

Install the package from CRAN:

install.packages("spbabel")

The development version can be installed directly from github:

devtools::install_github("mdsumner/spbabel")

Formal spatial data in R

Spatial data in the sp package have a formal definition (extending class Spatial) that is modelled on shapefiles, and close at least in spirit to the Simple Features definition. See What is Spatial in R? for more details.

Turning these data into long-form tables has been likened to making fish soup, which has a nice nod to the universal translator babelfish. Soup may be thick and creamy as in the "twice cooked" bisque or clear as in the "boiled" bouillon and this analogy can be applied in many ways.

The spbabel package tries to help by providing a more systematic encoding into the long-form with consistent naming and lossless ways to re-compose the original (or somewhat modified) objects.

The long-form version is similar to that implemented in:

  • sp's as() coercion for SpatialLinesDataFrame to SpatialPointsDataFrame
  • rasters's geom()
  • ggplot2's fortify()
  • gris' normalized tables

How does spbabel work

After quite a lot of experimentation the long-form single table of all coordinates, with object, branch, island-status, and order provides the best middle-ground for transferring between different representations of Spatial data. Tables are always based on the "tibble" since it's a much better data frame.

The sptable function creates the table of coordinates with identifiers for object and branch, which is understood by sptable<- to "fortify" and sp for the reverse.

The long-form table may seem like soup, but it's not meant to be seen for normal use. It's very easy to dump this to databases, or to ask spatial databases for this form. There are other more normalized multi-table approaches as well - this is just a powerful lowest common denominator.

We can tidy this up by encoding the geometry data into a geometry-column, into nested data frames, or by normalizing to tables that store only one kind of data, or with recursive data structures such as lists of matrices. Each of these has strengths and weaknesses. Ultimately I want this to evolve into a fully-fledged set of tools for representing spatial/topological data in R, but still by leveraging existing code whereever possible.

sptable: a round-trip-able extension to fortify

The sptable function decomposes a Spatial object to a single table structured as a row for every coordinate in all the sub-geometries, including duplicated coordinates that close polygonal rings, close lines and shared vertices between objects.

The sp function re-composes a Spatial object from a table, it auto-detects the topology by the matching column names:

  • SpatialPolygons: object_, branch_, island_, order_
  • SpatialLines: object_, branch_, order_
  • SpatialPoints: object_
  • SpatialMultiPoints: object_, branch_

The sp function could include overrides to avoid these tests but it's so easy to modify a table to have the matches for the required topology it hardly seems worth it.

Use the sptable<- replacement method to modify the underlying geometric attributes (here x and y is assumed no matter what coordinate system).

library(maptools)
#> Loading required package: sp
#> Checking rgeos availability: TRUE
data(wrld_simpl)
library(spbabel)
(oz <- subset(wrld_simpl, NAME == "Australia"))
#> class       : SpatialPolygonsDataFrame 
#> features    : 1 
#> extent      : 112.9511, 159.1019, -54.74973, -10.05167  (xmin, xmax, ymin, ymax)
#> coord. ref. :  +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0 
#> variables   : 11
#> Source: local data frame [1 x 11]
#> 
#>     FIPS   ISO2   ISO3    UN      NAME   AREA  POP2005 REGION SUBREGION
#>   (fctr) (fctr) (fctr) (int)    (fctr)  (int)    (dbl)  (int)     (int)
#> 1     AS     AU    AUS    36 Australia 768230 20310208      9        53
#> Variables not shown: LON (dbl), LAT (dbl)

## long-form encoding of objects
oztab <- sptable(oz)

##  make a copy to modify
woz <- oz
## modify the geometry on this object without separating the vertices from the objects
sptable(woz) <- sptable(woz) %>% mutate(x_ = x_ - 5)

# plot to compare 
plot(oz, col = "grey")
plot(woz, add = TRUE)

We can also restructure objects, by mutating the value of object to be the same as "branch" we get individual objects from each.


pp <- sptable(wrld_simpl %>% subset(NAME == "Japan" | grepl("Korea", NAME)))
## explode (or "disaggregate"") objects to individual polygons
## here each branch becomes an object, and each object only has one branch
## (ignoring hole-vs-island status for now)
wone <- sp(pp %>% mutate(object_ = branch_), crs = attr(pp, "crs"))
op <- par(mfrow = c(2, 1), mar = rep(0, 4))
plot(sp(pp), col = grey(seq(0.3, 0.7, length = length(unique(pp$object)))))
plot(wone, col = sample(rainbow(nrow(wone), alpha = 0.6)), border = NA)

par(op)

The long-form table is also ready for ggplot2:

library(ggplot2)
ggplot(pp) + aes(x = x_, y = y_, fill = factor(object_), group = branch_) + geom_polygon()


ggplot(pp) + aes(x = x_, y = y_, fill = factor(branch_), group = branch_, col = object_) + geom_polygon()

Please note that that geom_polygon cannot handle islands with multiple holes, and it only can do one hole by pretending it is a closed path and hides the boundary so you don't see the sleight of hand. Search for "geom_holygon" for a way forward within ggplot2.

Why do this?

I want these things, and spbabel is the right compromise for where to start:

  • flexibility in the number and type/s of attribute stored as "coordinates", x, y, lon, lat, z, time, temperature, etc.
  • shared vertices
  • ability to store points, lines and areas together, sharing topology where appropriate
  • provide a flexible basis for conversion between other formats.
  • flexibility and ease of use
  • integration with database engines and other systems
  • integration with D3 via htmlwidgets, with shiny, and with gggeom ggvis or similar
  • data-flow with dplyr piping as the engine behind a D3 web interface

The ability to use Manifold System seamlessly with R is a particular long-term goal, and this will be best done(TM) via dplyr "back-ending".

Copy Link

Version

Install

install.packages('spbabel')

Monthly Downloads

246

Version

0.3.2

License

GPL-3

Maintainer

Michael D. Sumner

Last Published

June 22nd, 2016

Functions in spbabel (0.3.2)

semap

"South-east" map data.
sptable

Convert from Spatial*DataFrame to table.
mpoint1

MultiPointsDataFrame data set
sp

Convert from dplyr tbl form to Spatial*DataFrame.
spbabel-package

A basis for converting between different types of spatial objects.
show,SpatialPolygonsDataFrame-method

sp methods