Skip to contents

The term spatio-temporal data can incorporate various spatial and temporal characteristics and different data may require different data structures for wrangling and analysis. The spatio-temporal data that cubble addresses are those collected at unique fixed locations, allowing for irregularity in the temporal dimension, such as the weather station data.

Beyond data wrangling, cubble makes glyph maps native to ggplot2: geom_glyph() draws each location’s time series as a small plot at that location, so spatial and temporal patterns can be seen in a single plot.

Installation

You can install the released version of cubble from CRAN with:

And the development version from GitHub with:

# install.packages("remotes")
remotes::install_github("huizezhang-sherry/cubble")

How cubble organises spatio-temporal data

Cubble organises spatio-temporal data in two structures: In a nested cubble (spatial cubble), spatial variables are organised as columns and temporal variables are nested within a specialised ts column:

#> # cubble:   key: id [3], index: date, nested form
#> # spatial:  [144.83, -37.98, 145.1, -37.67], Missing CRS!
#> # temporal: date [date], prcp [dbl], tmax [dbl], tmin [dbl]
#>   id           long   lat  elev name              wmo_id ts               
#>   <chr>       <dbl> <dbl> <dbl> <chr>              <dbl> <list>           
#> 1 ASN00086038  145. -37.7  78.4 essendon airport   95866 <tibble [10 × 4]>
#> 2 ASN00086077  145. -38.0  12.1 moorabbin airport  94870 <tibble [10 × 4]>
#> 3 ASN00086282  145. -37.7 113.  melbourne airport  94866 <tibble [10 × 4]>

In a long cubble (temporal cubble), the temporal variables are expanded into the long form, while the spatial variables are stored as a data attribute:

#> # cubble:   key: id [3], index: date, long form
#> # temporal: 2020-01-01 -- 2020-01-10 [1D], no gaps
#> # spatial:  long [dbl], lat [dbl], elev [dbl], name [chr], wmo_id [dbl]
#>    id          date        prcp  tmax  tmin
#>    <chr>       <date>     <dbl> <dbl> <dbl>
#>  1 ASN00086038 2020-01-01     0  26.8  11  
#>  2 ASN00086038 2020-01-02     0  26.3  12.2
#>  3 ASN00086038 2020-01-03     0  34.5  12.7
#>  4 ASN00086038 2020-01-04     0  29.3  18.8
#>  5 ASN00086038 2020-01-05    18  16.1  12.5
#>  6 ASN00086038 2020-01-06   104  17.5  11.1
#>  7 ASN00086038 2020-01-07    14  20.7  12.1
#>  8 ASN00086038 2020-01-08     0  26.4  16.4
#>  9 ASN00086038 2020-01-09     0  33.1  17.4
#> 10 ASN00086038 2020-01-10     0  34    19.6
#> # ℹ 20 more rows

The two forms can be pivoted back and forth with the pair of verb: face_spatial() and face_temporal().

Glyph maps

A glyph map draws each location’s time series as a small plot, a glyph, at that location. cubble provides geom_glyph(), with geom_glyph_box() and geom_glyph_line() for reference boxes and lines, as ggplot2 layers. They take four aesthetics: x_major and y_major for the location, and x_minor and y_minor for the time series inside each glyph. Below, each glyph shows the proportion of water samples above the bacteria guideline in the 0–6 days after heavy rain at Sydney swim sites: ocean beaches clear within two days, while inner harbour sites stay polluted for longer.

library(ggplot2)
beach <- read.csv(system.file("extdata/sydney-beach.csv", package = "cubble"))
sydney <- sf::st_read(system.file("extdata/sydney-land.geojson", package = "cubble"), 
                      quiet = TRUE)

ggplot(beach, aes(x_major = long, y_major = lat,
                  x_minor = days_after_rain, y_minor = unsafe,
                  colour = water, group = swim_site)) +
  geom_sf(data = sydney, fill = "#ECEAE4", colour = NA, inherit.aes = FALSE) +
  geom_glyph_box(width = 0.028, height = 0.012, colour = "#9CADB7") +
  geom_glyph(width = 0.028, height = 0.012, linewidth = 0.6, key_glyph = "path") +
  scale_colour_manual(values = c("#BF5700", "#005F86"), name = NULL) +
  coord_sf(xlim = c(151.11, 151.32), ylim = c(-34.0, -33.72)) +
  theme_void() +
  theme(legend.position = "bottom",
        panel.background = element_rect(fill = "#e8f3ff", colour = NA))

For summaries that are an interval rather than a single value, such as the daily minimum and maximum temperature, the sugarglider package extends cubble’s glyph maps with geom_glyph_segment() and geom_glyph_ribbon().

Roadmap