--- title: "Tidy csquares" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Tidy csquares} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ggplot2::theme_set(ggplot2::theme_light()) ``` ## The Csquares family `csquares` objects can inherit properties from different parents as illustrated in `vignette("csquares-objects")`. When a `csquares` object inherits from the class `data.frame()`, you can apply many [tidyverse](https://www.tidyverse.org/) operations while preserving the `csquares` properties of the object. When you create a `csquares` object from a `character()`, you cannot use tidyverse operations as it doesn't inherit the `data.frame()` class. You can check which ancestors your object has by calling `class()` as shown in the example below. ```{r no-tidy, warning=FALSE, message=FALSE} ## Required libraries library(csquares) library(dplyr) library(sf) library(ggplot2) ## create a simple csquares object: char_csq <- as_csquares(c("1000", "3000")) ## This simple objects has "character" as parent class. ## So tidyverse is out of the question here. class(char_csq) ``` So let's start by creating a `csquares` object that does inherit from the `data.frame()` class. It will be used in examples shown in this vignette. ```{r yes-tidy} ## create a csquares object with geometries: orca_csq <- orca |> as_csquares(csquares = "csquares") ## It inherits the class data.frame. class(orca_csq) ``` ## Tidyverse operations All tidyverse (and base) methods implemented in the Csquares package end with the suffix `.csquares`. You should never call these functions directly as this will likely produce errors. Instead, load the packages that implement the generic method (e.g., `dplyr` for `mutate()` and `summarise()`; `tidyr` for `pivot_wider()`; `sf` for `st_as_sf()` etc.). Then call the method without the `.csquares` suffix as shown in the examples below. As you call the method on `csquares` objects, the correct implementation of the generic method will be dispatched automatically. The example below shows how you can mutate a column in a `csquares` object, then group by a specific column and summarise it. The csquares properties are grouped automatically. If the `csquares` object inherits spatial features, the geometries are recalculated after summarising. ```{r mutate, warning=FALSE} orca_sum <- orca_csq |> ## Add geometries to the object st_as_sf() |> ## use `mutate` to create a column that contains the csquares' quadrant mutate(quadrant = case_match(substr(csquares |> as.character(), 1L, 1L), "1" ~ "NE", "3" ~ "SE", "5" ~ "SW", "7" ~ "NW")) |> ## grouping by the column with logical values and summarising ## will reduce the number of rows to 4 (one for each quadrant) group_by(quadrant) |> summarise(realms = sum(orcinus_orca), .groups = "keep") ## Note that csquares are automatically concatted and ## geometries recalculated ggplot(orca_sum) + geom_sf(aes(fill = realms)) + geom_sf_text(aes(label = quadrant)) + coord_sf() + labs(title = "Realm count per quadrant", x = NULL, y = NULL) ``` Printing the summarised object shows that there are only two rows left. One for each value in the grouped column. ```{r show_sum} orca_sum ``` ## Join Joining `csquares` objects is pretty straightforward and is only allowed on objects that inherit from the `data.frame` class. An exception are `csquares` objects that inherit from the `stars` class (`stars::st_as_stars()`). On those objects you are allowed to perform left joins, all other joins are impossible. See also `?join`. Below you see how you can simply join a `data.frame` to a `csquares` object by the csquares code. ```{r join} df <- data.frame(foo = "bar", csquares = "3603:3") left_join(orca_csq, df, by = "csquares") |> print(max = 30) right_join(orca_csq, df, by = "csquares") ``` You are also allowed to join a `csquares` object to another `csquares` by another column that does not represent the csquares codes: ```{r join_extra} csq <- data.frame(orcinus_orca = FALSE, csquares = "3603:3") |> as_csquares(csquares = "csquares") left_join(orca_csq, csq, by = "orcinus_orca") |> print(max = 30) ``` Note that the resulting `csquares` object has two columns with csquares codes. Only the column from the left-hand table in the join is used for further operations. However, you should wonder if this join is meaningful when mismatching csquares codes are the result. ## Further reading For some additional `csquares` specific examples check out `?tidyverse` and `?join`. For extensive documentation on tidy operations, consult the [tidyverse website](https://www.tidyverse.org).