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.41132If 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.86Alternatively, 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)$COUNTRYTo 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 2806808As 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).