Csquares objects

library(csquares)

The S3 class csquares

The csquares package has defined a csquares class. Objects that are of this class contain a character vector or is a character vector itself, where the characters represent valid csquares codes. The advantage to have a distinct class for these objects is that you automatically inherit all methods that are available for parent classes. The csquares object can essentially inherit from the following classes (arranged from simplest to most complex):

  • character vectors;
  • data.frame;
  • spatial classes:
    • sf (sf::st_sf());
    • stars (stars::st_as_stars()).

It is important to realise that csquare objects can have varying parents, which is visualised in the diagram below. What you can do with csquares objects in part depends on its parent. Let’s start with showing how csqaures objects are created and how they will inherit properties from the different parents listed above.

Csquares schematic cluster_dfc data.frame csquare cluster_char character csquare csquares csquares strucstrs stars::stars csquares strucstrs:starscsq->csquares strucdf data.frame csquares strucdf:dfcsq->csquares strucsf sf::sf csquares strucdf:df->strucsf:sf strucsf:sfcsq->csquares strucchar character csquares strucchar:charcsq->csquares strucchar:charcsq->strucdf:dfcsq strucchar:charcsq->strucsf:sfcsq vctr vctrs::vctrs_vctr vctr->strucchar:character

Creating csquares objects

Using characters

The simplest way of creating a csquares object is by coercing other objects with as_csquares(). The example below shows how to create a csquares object from a vector of characters:

csquares_char <- as_csquares(c("1000", "3000", "5000", "7000"))

Using data.frames

Perhaps a more useful format is a data.frame, as you can add data associated with the spatial squares. You can cast the previous object to a data.frame and it will automatically inherit the csquares class:

csquares_df <- as.data.frame(csquares_char)

class(csquares_df)
#> [1] "csquares"   "data.frame"

This means that you can apply all operations that you could apply to a normal data.frame. This includes tidyverse operations as explained in more detail in vignette("tidy"). For example, you can add columns with data:

library(dplyr)

csquares_df <-
  csquares_df |>
  mutate(dummy = 1:4)

You can also cast a plain data.frame to a csquares object. In that case, your data.frame should already contain a column with csquares codes. All you have to do is specify which column this is:

orca_csq <- as_csquares(orca, csquares = "csquares")

Using Simple Features (sf)

Remember that csquares encode geographic rectangles, so it makes sense to include this spatial information in the data.frame. This is achieved by coercing a csquares data.frame to a simple features (sf) object. It too will automatically inherit the csquares class:

library(sf)
csquares_sf <- st_as_sf(csquares_df)

The object csquares_sf now has a column holding the csquares codes and a column containing the corresponding geometric features. Both should represent the same spatial object. But be careful! Not all methods are aware of this, so modifying the geometric column might break this association.

Using Spatiotemporal Arrays (stars)

csquares objects inheriting from the stars are a little trickier. This is because there are more constraints: You cannot include just any csquares at any location with varying resolutions. At the moment csquares only support regular linear grids where each grid cell size is the same as that of the associated csquares. To create a csquares stars object, you have to provide a bounding box and a resolution in degrees:

library(stars)

csquares_stars <- new_csquares(csquares_sf, resolution = 10L)

Even though we use the csquares_sf object to create the grid, it doesn’t include any of the columns from the sf object in the resulting stars object. That is because only the bounding box of csquares_sf is used to create csquares_stars. You can add information to the grid by matching the csquares codes:

## create an empty column:
csquares_stars[["dummy"]] <- NA
csquares_stars[["dummy"]] <-
  csquares_df[["dummy"]] [
    match(csquares_stars[["csquares"]], csquares_df[["csquares"]])
  ]

Or simply use left_join():

csquares_stars <-
  left_join(csquares_stars,
            data.frame(csquares = "1000", foo = "bar"),
            by = "csquares")

Validating csquares objects

When creating a csquares object with as_csquares, it is not allowed to pass illegal codes, or codes with wildcards (see vignette("wildcards")). It will throw an error. You could try to work around this and create a fake csquares object by assigning the class manually to an illegal code. However, if you test its validity you will see that it is not going to fly:

## Let's create a fake csquares object with a code that is merely impossible:
fake_csquares <- "1099"
class(fake_csquares) <- "csquares"

## Of course this isn't valid
validate_csquares(fake_csquares)
#> [1] FALSE

## This one is:
validate_csquares(csquares_char)
#> [1] TRUE