Spatial Data and Analyses in R

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:

### Add or update a single column
cities$bio1 <- terra::extract(rstack[["bio1"]], cities)$bio1

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).