Chapter 6 Overlaying data
If we want to get the values of the raster layers at specified (point) locations, we can use the extract
function. The result is a data.frame with a column per layer (with the name of the layer in the raster), as well as the ID of the point for which data is extracted, and a row per location.
Note that the extract
function is also part of other packages, so sometimes it may be needed to use the extract
function from the terra
package specifically, by calling terra::extract(...)
:
### Extract value for all layers in rstack, for the coordinates of the cities
terra::extract(rstack, cities)
## ID bio1 bio4 bio5 bio12 dwater
## 1 1 9.635555 556.9976 22.56530 809.8702 95.64172
## 2 2 11.722191 566.5977 24.71778 635.7020 150.07396
## 3 3 10.734476 492.7936 23.18519 637.1843 76.86348
## 4 4 9.625695 692.0491 23.91142 567.7325 150.55394
## 5 5 10.398586 553.3554 22.80056 786.8825 88.87450
## 6 6 10.227142 752.1799 25.67422 582.8508 635.41132
If we want to add the extracted values as new columns to an already existing object (e.g. cities
), we can use the cbind
function which column-binds data:
### Column-bind the values of all layers to the table with city locations
cities <- cbind(cities, terra::extract(rstack, cities))
# Inspect
cities
## class : SpatVector
## geometry : points
## dimensions : 6, 7 (geometries, attributes)
## extent : 3620499, 4794946, 2806808, 3272423 (xmin, xmax, ymin, ymax)
## coord. ref. : ETRS89-extended / LAEA Europe
## names : city ID bio1 bio4 bio5 bio12 dwater
## type : <chr> <num> <num> <num> <num> <num> <num>
## values : Wageningen 1 9.636 557 22.57 809.9 95.64
## Paris 2 11.72 566.6 24.72 635.7 150.1
## London 3 10.73 492.8 23.19 637.2 76.86
Alternatively, we can use the $
operator to add (or update) a single column to an existing object, if we extract values from a single raster:
If we want overlay vector data over vector data, e.g. if to extract properties from a polygon vector (like countries
loaded earlier) for each of the locations in cities
, than we can also use the extract
function from package terra
. The properties of the countries
object loaded earlier include multiple columns, so rather than including them all in the cities
object lets just add the column COUNTRY
(and assign it to a column called country
in cities
):
### Add country name using a spatial join to the countries object
cities$country <- terra::extract(countries, cities)$COUNTRY
To view the entire table with data, including the coordinates of the geometries (i.e. points), we can use the as.data.frame
function:
### View data
as.data.frame(cities, geom = "XY")
## city ID bio1 bio4 bio5 bio12 dwater country x y
## 1 Wageningen 1 9.635555 556.9976 22.56530 809.8702 95.64172 Netherlands 4023281 3217249
## 2 Paris 2 11.722191 566.5977 24.71778 635.7020 150.07396 France 3756381 2890119
## 3 London 3 10.734476 492.7936 23.18519 637.1843 76.86348 United Kingdom 3620499 3202910
## 4 Berlin 4 9.625695 692.0491 23.91142 567.7325 150.55394 Germany 4550149 3272423
## 5 Brussels 5 10.398586 553.3554 22.80056 786.8825 88.87450 Belgium 3923375 3102445
## 6 Vienna 6 10.227142 752.1799 25.67422 582.8508 635.41132 Austria 4794946 2806808
As we can see, the country data are correctly linked to the cities, and on average the temperature in Paris is the highest and Berlin the lowest; in Vienna the temperature seasonality is the highest (thus strong contrast between cold winter temperatures and high summer temperatures); the temperature of the warmest month is highest in Vienna, and Brussels has the highest annual precipitation. Moreover, we see that Vienna is the furthest from any sea or ocean (more than 600 km), whereas Wageningen and London are quite close (less than 100 km).