Learn how to handle raster datasets using R.
ggplot2
Click on the three horizontally stacked lines at the bottom left corner of the slide, then you will see table of contents, and you can jump to the section you want
Hit letter “o” on your keyboard and you will have a panel view of all the slides
terra
and raster
packages: BasicsThe most popular R packages to handle raster data is the raster
and terra
packages. They are authored by the same person and terra
is the successor of raster
.
The terra
package is now mature and does everything faster than raster
There are lots of packages that still depends on raster
and do not work well with R object class defined by terra
.
We primarily learns how to use the terra
package
The terra
and raster
packages use different R object class to represent raster data:
terra
SpatRaster
raster
(collectively referred to as Raster
*)
RasterLayer
RasterStack
RasterBrick
Note
SpatRaster
to Raster
* and vice versa.Raster
*, especially the ones that are old.Let’s take a look at a SpatRaster
object, reflec_blue
.
Check the class first:
What is inside?
Here are the explanations of the information provided:
st_bbox(sf)
)You can use plot()
to make a map quickly:
It automatically color the grids by the value of the attribute (blue
).
You can simply use c()
function to create a multi-layer SpatRaster
just like you create a vector as long as all the layers have exactly the same dimensions, extent, and resolution.
Notice that nlyr
is 3 now and you see three attribute names in names
.
plot()
create maps for all the attributes.
The raster
package differentiates single-layer and multi-layer raster data.
RasterLayer
: single-layerRasterStack
: multi-layerRasterBrick
: multi-layerYou can convert a SpatRaster
to a Raster
* object using as(SpatRaster, "Raster")
.
Since, reflec_blue
is a single-layer SpatRaster
, it was converted into a RasterLayer
.
Since, reflec_all
is a multi-layer SpatRaster
, it was converted into a RasterBrick
.
Note
You can convert a RasterBrick
to a RasterStack
by applying stack()
to the RasterBrick
if you want. But, you do not need to.
You can convert an Raster
* object to SpatRaster
using terra::rast()
function.
This is very useful. As we will see later, when interacting two spatial objects (e.g., extracting values from a raster data to sf
) some functions require that the two spatial objects has the same CRS. You can use terra::crs()
to get the CRS of the raster data and apply it to another spatial object.
This is like st_bbox()
for sf
.
You can access the cell values using []
just like a vector. Note that head()
is there to avoid a very long vector presented on the console.
Yes, there are so many NAs in this raster data. Let’s look at the value of 10100th through 10200th cells:
Note
Raster data files can come in numerous different formats.
You can read data of almost all the existing file formats with the terra
package.
You can use terra::rast()
to read raster data files.
single raster data file
multiple raster data files
Instruction
single file
It looks like this for me:
multiple files
It looks like this for me:
Instruction
It has a different file extension of .bil. Well it does no matter. Just use terra::rast()
with path to the file inside it just like you did with the GeoTiff files.
This is what the code looks like for me:
You can use terra::writeRaster()
to write raster data to a data file.
Syntax
Example (does not run)
This code saves reflec_blue
(a SpatRaster
object) as a GeoTiff file.
writeRaster()
infers the correct format from the extension of the file name, which if .tif here.
The overwrite = TRUE
option is necessary if a file with the same name already exists and you are overwriting it.
Note
No distinction is necessary for single-layer and multi-layer SpatRaster
objects.
single-layer
Write reflec_blue
on your computer. Mine looks like this:
Then read it back:
Confirm that reflec_blue_re_read
is the same as reflec_blue
.
multi-layer
Write reflec_all
on your computer. Mine looks like this:
Then read it back:
Confirm that reflec_all_re_read
is the same as reflec_all
.
You can do basic arithmetic operations (addition, subtraction, division, etc) using raster layers as long as they share the same spatial extent and resolution
You can also apply a function like log()
to transform the value of the cells
Raster arithmetic operations are done element-by-element (cell-by-cell) just like vector arithmetic operations.
For example, when two RasterLayer
s are added, then the two values associated with the same cell are added and the resulting value becomes the new value for the cell in the newly created RasterLayer
.
Did it work?
Yes, looks like it did. Look at different cells yourself. Note that the name of the attribute in reflec_b_plus_g
inherited the name of the attribute in reflec_blue
(first SpatRaster
in the addition above).
Multiply reflec_blue
with reflec_red
and add square root of reflec_green
:
Look at several cells to confirm that multiplication was successful.
Answer:
Sometimes, you want to make your raster data have a lower resolution. For example, satellite image is often very fine with spatial resolution of say 30cm. When trying to create a map using the data, it takes long time for R to render a plot and also the size of the figure can be very large.
Syntax
fact
:Example
Let’s compare before and after. After aggregating by factor of 5, the map is visibly more coarse. Maybe this was too much.
You have two raster layers that differ in any of the dimension and resolution.
You want to assign a value from one layer to each of the cells in the other layer so that you have consistent observation units for the variables from the two layers.
Fake precipitation data:
Fake soil data:
Map below shows grids from precip
(red border) and from soil
(blue border).
As you can see, the grids from the two layers are not nicely aligned.
See the the top left grid with green fill color from the precip
layer. Resampling will find a single value to the grid based on the value of the nearby grids from the soil
layer.
Even though the name “resample” sounds like it is a random process, there is no randomness.
Syntax
st_1
: SpatRaster
to be resampledst_2
: SpatRaster
with the geometry that st_1
should be resampled tomethod
: method of assigning values
?terra::resample
to see all the method
options)Since we are resampling values from the soil
layer to the grids of precip
,
Try yourself
method
and see how the resampling results change.method
as you see here where cell values are completely independent.Sometimes, you have two or more raster layers that have different spatial coverages. In such a case, you might want to merge them into a single raster layer.
For demonstration purpose, we will use two SpatRaster
objects: prism_saunders
and prism_douglas
. They are PRISM maximum temperature observed on 08/01/2012 in the Saunders and Douglas counties in Nebraska, which are adjacent to each other.
Note
Note that this is different from combining multiple single-layer raster data of the same spatial extent and resolution into multi-layer raster data.
You can use the terra::merge()
function to merge two raster datasets into one.
You can check the result of the merging below:
Note
Remember that raster object has to be perfectly rectangular. The result of merging will construct a rectangle that encompasses both prism_saunders
and prism_douglas
. All the cells that are not covered by prism_saunders
and prism_douglas
will be assigned NA.
When merging two SpatRaster
objects and when they have spatial overlaps, the value of the first SpatRaster
object will be respected.
Let’s run a little experiment. We will assign a high value to all the cells in prism_saunders
. This will make this phenomenon easy to detect.
prism_saunders
first
prism_douglas
first