The goal of tidyterra is to provide common
tidyverse methods for
SpatRaster and SpatVector objects created with the
terra package. It also
provides ggplot2 geoms and scales
for plotting those objects.
Please cite tidyterra as:
Hernangómez, D. (2023). Using the tidyverse with terra objects: the tidyterra package. Journal of Open Source Software, 8(91), 5751, https://doi.org/10.21105/joss.05751.
A BibTeX entry for LaTeX users is:
@article{Hernangómez2023,
doi = {10.21105/joss.05751},
url = {https://doi.org/10.21105/joss.05751},
year = {2023},
publisher = {The Open Journal},
volume = {8},
number = {91},
pages = {5751},
author = {Diego Hernangómez},
title = {Using the {tidyverse} with {terra} objects: the {tidyterra} package},
journal = {Journal of Open Source Software}
}The full manual for the latest release of tidyterra on CRAN is online: https://dieghernan.github.io/tidyterra/
tidyverse methods implemented in tidyterra work differently
depending on the type of Spat* object:
-
SpatVector: the methods are implemented usingterra::as.data.frame()coercion. Rows correspond to geometries and columns correspond to attributes of each geometry. -
SpatRaster: methods can be applied to layers or cells. tidyterra’s overall approach is to treat the layers as columns of a tibble and the cells as rows (i.e.select(SpatRaster, 1)selects the first layer of aSpatRaster).
Implemented methods return the same type of object as the input, unless
the method is expected to return another type of object. For example,
as_tibble() returns a tibble.
Current methods and functions provided by tidyterra are:
| tidyverse method | SpatVector |
SpatRaster |
|---|---|---|
tibble::as_tibble() |
✔️ | ✔️ |
dplyr::select() |
✔️ | ✔️ Select layers |
dplyr::mutate() |
✔️ | ✔️ Create or modify layers |
dplyr::transmute() |
✔️ | ✔️ |
dplyr::filter() |
✔️ | ✔️ Modify cell values and optionally remove outer cells. |
dplyr::filter_out() |
✔️ | |
dplyr::slice() |
✔️ | ✔️ Additional methods for slicing by row and column. |
dplyr::pull() |
✔️ | ✔️ |
dplyr::rename() |
✔️ | ✔️ |
dplyr::relocate() |
✔️ | ✔️ |
dplyr::distinct() |
✔️ | |
dplyr::arrange() |
✔️ | |
dplyr::glimpse() |
✔️ | ✔️ |
dplyr::inner_join() family |
✔️ | |
dplyr::nest_join() |
✔️ | |
dplyr::cross_join() |
✔️ | |
dplyr::summarise() |
✔️ | |
dplyr::reframe() |
✔️ | |
dplyr::group_by() family |
✔️ | |
dplyr::rowwise() |
✔️ | |
dplyr::count(), tally() |
✔️ | |
dplyr::add_count() |
✔️ | |
dplyr::rows_*() |
✔️ | |
dplyr::bind_cols() / dplyr::bind_rows() |
✔️ as bind_spat_cols() / bind_spat_rows() |
|
tidyr::drop_na() |
✔️ | ✔️ Remove cell values with NA on any layer and outer cells with NA. |
tidyr::complete() |
✔️ | |
tidyr::expand() |
✔️ | |
tidyr::replace_na() |
✔️ | ✔️ |
tidyr::fill() |
✔️ | |
tidyr::nest() |
✔️ | |
tidyr::pivot_longer() |
✔️ | |
tidyr::pivot_wider() |
✔️ | |
tidyr::uncount() |
✔️ | |
tidyr::unite() |
✔️ | ✔️ Create a categorical layer. |
ggplot2::autoplot() |
✔️ | ✔️ |
ggplot2::fortify() |
✔️ to sf through sf::st_as_sf() |
To a tibble with coordinates. |
ggplot2::geom_*() |
✔️ geom_spatvector() |
✔️ geom_spatraster() and geom_spatraster_rgb(). |
generics::tidy() |
✔️ | ✔️ |
generics::glance() |
✔️ | ✔️ |
generics::required_pkgs() |
✔️ | ✔️ |
Important
tidyterra is a user-friendly wrapper around terra that provides tidyverse methods and verbs. This approach has a performance cost.
If you frequently use terra or work with large SpatRaster
objects, terra is usually much faster. Whenever possible, each
tidyterra function refers to its equivalent on terra.
As a rule of thumb, if your raster has fewer than 10,000,000 data
slots (i.e. terra::ncell(your_rast) * terra::nlyr(your_rast) < 1e7),
tidyterra is a good fit.
When plotting rasters, resampling is performed automatically (as
terra::plot() does, see the help page). You can adjust this with the
maxcell argument.
Install tidyterra from CRAN:
install.packages("tidyterra")Check the documentation for the development version at https://dieghernan.github.io/tidyterra/dev/
You can install the development version of tidyterra with:
# install.packages("pak")
pak::pak("dieghernan/tidyterra")Alternatively, you can install tidyterra using r-universe:
# Enable this universe
install.packages(
"tidyterra",
repos = c(
"https://dieghernan.r-universe.dev",
"https://cloud.r-project.org"
)
)This basic example shows how to manipulate and plot SpatRaster
objects:
library(tidyterra)
library(terra)
# Temperatures
rastertemp <- rast(system.file("extdata/cyl_temp.tif", package = "tidyterra"))
rastertemp
#> class : SpatRaster
#> size : 87, 118, 3 (nrow, ncol, nlyr)
#> resolution : 3881.255, 3881.255 (x, y)
#> extent : -612335.4, -154347.3, 4283018, 4620687 (xmin, xmax, ymin, ymax)
#> coord. ref. : World_Robinson (ESRI:54030)
#> source : cyl_temp.tif
#> names : tavg_04, tavg_05, tavg_06
#> min values : 1.885463, 5.817587, 10.463377
#> max values : 13.283829, 16.740898, 21.113781
# Rename
rastertemp <- rastertemp |>
rename(April = tavg_04, May = tavg_05, June = tavg_06)
# Facet all layers
library(ggplot2)
ggplot() +
geom_spatraster(data = rastertemp) +
facet_wrap(~lyr, ncol = 2) +
scale_fill_whitebox_c(
palette = "muted",
labels = scales::label_number(suffix = "º"),
n.breaks = 12,
guide = guide_legend(reverse = TRUE)
) +
labs(
fill = "",
title = "Average temperature in Castile and Leon (Spain)",
subtitle = "Months of April, May and June"
)# Create the difference between two months.
variation <- rastertemp |>
mutate(diff = June - May) |>
select(variation = diff)
# Add a SpatVector overlay.
prov <- vect(system.file("extdata/cyl.gpkg", package = "tidyterra"))
ggplot(prov) +
geom_spatraster(data = variation) +
geom_spatvector(fill = NA) +
scale_fill_whitebox_c(
palette = "deep",
direction = -1,
labels = scales::label_number(suffix = "º"),
n.breaks = 5
) +
theme_minimal() +
coord_sf(crs = 25830) +
labs(
fill = "Variation",
title = "Temperature variation in Castile and Leon (Spain)",
subtitle = "Average temperatures: June vs. May"
)tidyterra also provides a geom for plotting RGB SpatRaster
objects, such as map tiles, with ggplot2:
rgb_tile <- rast(system.file("extdata/cyl_tile.tif", package = "tidyterra"))
ggplot(prov) +
geom_spatraster_rgb(data = rgb_tile) +
geom_spatvector(fill = NA) +
theme_light() +
# Change the CRS and datum (useful for relabeling graticules).
coord_sf(crs = 3857, datum = 3857)tidyterra provides scales for plotting maps with hypsometric tints and ggplot2:
asia <- rast(system.file("extdata/asia.tif", package = "tidyterra"))
ggplot() +
geom_spatraster(data = asia) +
scale_fill_hypso_tint_c(
palette = "gmt_globe",
labels = scales::label_number(),
# Further refinements
breaks = c(-10000, -5000, 0, 2000, 5000, 8000),
guide = guide_colorbar(reverse = TRUE)
) +
labs(
fill = "elevation (m)",
title = "Hypsometric map of Asia"
) +
theme(
legend.position = "bottom",
legend.title.position = "top",
legend.key.width = rel(3),
legend.ticks = element_line(colour = "black", linewidth = 0.3),
legend.direction = "horizontal"
)This basic example shows how to manipulate and plot SpatVector
objects:
vect(system.file("ex/lux.shp", package = "terra")) |>
mutate(pop_dens = POP / AREA) |>
glimpse() |>
autoplot(aes(fill = pop_dens)) +
scale_fill_whitebox_c(palette = "pi_y_g") +
labs(
fill = "population per km2",
title = "Population density of Luxembourg",
subtitle = "By canton"
)
#> # A SpatVector 12 x 7
#> # Geometry type: Polygons
#> # Geodetic CRS: lon/lat WGS 84 (EPSG:4326)
#> # Extent (x / y): ([5° 44' 38.9" E / 6° 31' 41.71" E] , [49° 26' 52.11" N / 50° 10' 53.84" N])
#>
#> $ ID_1 <dbl> 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3
#> $ NAME_1 <chr> "Diekirch", "Diekirch", "Diekirch", "Diekirch", "Diekirch", "…
#> $ ID_2 <dbl> 1, 2, 3, 4, 5, 6, 7, 12, 8, 9, 10, 11
#> $ NAME_2 <chr> "Clervaux", "Diekirch", "Redange", "Vianden", "Wiltz", "Echte…
#> $ AREA <dbl> 312, 218, 259, 76, 263, 188, 129, 210, 185, 251, 237, 233
#> $ POP <dbl> 18081, 32543, 18664, 5163, 16735, 18899, 22366, 29828, 48187,…
#> $ pop_dens <dbl> 57.95192, 149.27982, 72.06178, 67.93421, 63.63118, 100.52660,…Please leave your feedback or open an issue on https://github.com/dieghernan/tidyterra/issues.
Check the FAQs or open a new issue.
You can also ask in Stack Overflow using the tag [tidyterra].
tidyterra’s ggplot2 geoms are based on the ggspatial implementation by Dewey Dunnington and ggspatial contributors.