Conversions between different spatial classes in R
vignette
Author
Jakub Nowosad
Published
June 17, 2021
The R programming language has, over the past two decades, evolved substantial spatial data analysis capabilities, and is now one of the most powerful environments for undertaking geographic research using a reproducible command line interface. Currently, dedicated R packages allow to read spatial data and apply a plethora of different kinds of spatial methods in a reproducible fashion.
There are two main1 spatial data models - spatial vector data and spatial raster data. Natively R does not support spatial data and does not have a definition of spatial classes. Therefore, there had been a need to create R tools able to represent spatial vector and raster data. Spatial classes are slightly different from regular R objects, such as data frames or matrices, as they need to not only store values, but also information about spatial locations and their coordinate reference systems.
Nowadays, the most prominent packages to represent spatial vector data are sf(Pebesma 2021a) and its predecessor sp(Pebesma and Bivand 2021), however, the terra(Hijmans 2021b) package also has its own spatial class for vector data. Spatial raster data can be stored as objects from terra(Hijmans 2021b) and its predecessor raster(Hijmans 2021a), or alternatively the stars package (Pebesma 2021b).
As you could see in our Why R? webinar talk, the spatial capabilities of R constantly expand, but also evolve. New packages are being developed, while old ones are modified or superseded. In this process, new methods are created, higher performance code is added, and possible workflows are expanded. Alternative approaches allow for a (hopefully) healthy competition, resulting in better packages. Of course, having more than one package (with its own spatial class/es) for a vector or raster data model could be problematic, especially for new or inexperienced users.
First, it takes time to understand how different spatial classes are organized. To illustrate this, let’s read the same spatial data, srtm.tif from the spDataLarge package (Nowosad and Lovelace 2021), using raster and stars. The raster object:
stars object with 2 dimensions and 1 attribute
attribute(s):
Min. 1st Qu. Median Mean 3rd Qu. Max.
srtm.tif 1024 1535 1837 1842.548 2114 2892
dimension(s):
from to offset delta refsys point x/y
x 1 465 -113.24 0.000833333 WGS 84 FALSE [x]
y 1 457 37.5129 -0.000833333 WGS 84 FALSE [y]
Secondly, other packages with methods we want to use, could only accept one specific spatial class, but not the other. For example, the current version of the sabre package (Nowosad and Stepinski 2019) (0.3.2) accepts objects from the raster package, but not ones from terra or stars2. The partitions1 and partitions2 objects are of the RasterLayer class from raster, so the vmeasure_calc() function works correctly.
The SABRE results:
V-measure: 0.36
Homogeneity: 0.32
Completeness: 0.42
The spatial objects can be retrieved with:
$map1 - the first map
$map2 - the second map
However, when the input object (representing the same spatial data!) is of the SpatRaster class from terra, the calculation results in error.
## Error in UseMethod("vmeasure_calc") :
## no applicable method for 'vmeasure_calc' applied to an object of class "SpatRaster"
Some packages, such as tmap(Tennekes 2021), accept many R spatial classes, however, this takes a lot of effort from package creators to make it possible and to maintain it. Gladly, a number of functions exist that allow to convert between different R spatial classes. Using them, we can work with our favorite spatial data representation, switch to some other representation just for a certain calculation, and then convert the result back into our class. The next two sections showcase how to move between different spatial vector and raster data classes in R.
Now, we can read this file, for example, as an sf object, and convert it into other spatial vector data classes.
library(sf)library(sp)library(terra)# read as sfworld =read_sf(world_path)# sf to spworld_sp1 =as(world, "Spatial")# sf to terra vectworld_terra1 =vect(world)# sp to terra vectworld_terra2 =vect(world_sp1)# sp to sfworld_sf2 =st_as_sf(world_sp1)# terra vect to sfworld_sf3 =st_as_sf(world_terra1)# terra vect to spworld_sp2 =as(world_terra1, "Spatial")
In summary, st_as_sf() converts other classes into sf, vect() transform other classes into terra’s SpatVector, and with as(x, "Spatial") it is possible to get sp’s vectors.
FROM/TO
sf
sp
terra
sf
as(x, "Spatial")
vect()
sp
st_as_sf()
vect()
terra
st_as_sf()
as(x, "Spatial")
Spatial raster data
The srtm.tif file from the spDataLarge(Nowosad and Lovelace 2021) contains a raster elevation model for the Zion National Park in the USA.
Now, we can read this file, for example, as a raster object, and convert it into other spatial vector data classes.
library(raster)library(stars)library(terra)srtm_raster1 =raster(srtm_path)# raster to terrasrtm_terra1 =rast(srtm_raster1)# terra to rastersrtm_raster2 =raster(srtm_terra1)# raster to starssrtm_stars1 =st_as_stars(srtm_raster1)# stars to rastersrtm_raster2 =as(srtm_stars1, "Raster")# terra to starssrtm_stars2 =st_as_stars(srtm_terra1)# stars to terrasrtm_terra1a =as(srtm_stars1, "SpatRaster")
As you can see - in most cases, we can just use one function to move from one class to another.
FROM/TO
raster
terra
stars
raster
rast()
st_as_stars()
terra
raster()
st_as_stars()
stars
raster()
as(x, "SpatRaster")
Summary
This blog post summarizes how to move between different R spatial vector and raster classes. All of the functions mentioned above have one role: to change classes of input objects. They do not, however, change geometries or underlining values in the data.
Additionally, switching from the spatial vector data model to the spatial raster data model (and vice versa) is also possible. These operations are known as rasterization and vectorization, and they could impact spatial and nonspatial information in the input data. To learn more about them, read the Raster-Vector Interactions section in Geocomputation with R.
@online{nowosad2021,
author = {Nowosad, Jakub},
title = {Conversions Between Different Spatial Classes in {R}},
date = {2021-06-17},
url = {https://geocompx.org/post/2021/spatial-classes-conversion/},
langid = {en}
}