Cell-level functions¶
Introduction¶
The cell number is an important concept in the raster package. Raster
data can be thought of as a matrix, but in a SpatRaster
it is more
commonly treated as a vector. Cells are numbered from the upper left
cell to the upper right cell and then continuing on the left side of the
next row, and so on until the last cell at the lower-right side of the
raster. There are several helper functions to determine the column or
row number from a cell and vice versa, and to determine the cell number
for x, y coordinates and vice versa.
library(terra)
## terra 1.7.62
r <- rast(ncol=36, nrow=18)
ncol(r)
## [1] 36
nrow(r)
## [1] 18
ncell(r)
## [1] 648
rowFromCell(r, 100)
## [1] 3
colFromCell(r, 100)
## [1] 28
cellFromRowCol(r,5,5)
## [1] 149
xyFromCell(r, 100)
## x y
## [1,] 95 65
cellFromXY(r, cbind(0,0))
## [1] 343
colFromX(r, 0)
## [1] 19
rowFromY(r, 0)
## [1] 10
Accessing cell values¶
Cell values can be accessed with several methods. Use values
to get
all values or a single row; and valuesBlock
to read a block
(rectangle) of cell values.
r <- rast(system.file("ex/meuse.tif", package="terra"))
v <- values(r)
v[708:712]
## [1] NA NA NA NA NA
You can also read values using cell numbers or coordinates (xy) using
the extract
method.
cells <- cellFromRowCol(r, 50, 35:39)
cells
## [1] 3955 3956 3957 3958 3959
r[cells]
## meuse
## 1 743
## 2 706
## 3 646
## 4 686
## 5 758
xy <- xyFromCell(r, cells)
xy
## x y
## [1,] 179780 332020
## [2,] 179820 332020
## [3,] 179860 332020
## [4,] 179900 332020
## [5,] 179940 332020
extract(r, xy)
## meuse
## 1 743
## 2 706
## 3 646
## 4 686
## 5 758
You can also extract values using SpatialPolygons* or SpatialLines*. The default approach for extracting raster values with polygons is that a polygon has to cover the center of a cell, for the cell to be included. However, you can use argument “weights=TRUE” in which case you get, apart from the cell values, the percentage of each cell that is covered by the polygon, so that you can apply, e.g., a “50% area covered” threshold, or compute an area-weighted average.
In the case of lines, any cell that is crossed by a line is included. For lines and points, a cell that is only ‘touched’ is included when it is below or to the right (or both) of the line segment/point (except for the bottom row and right-most column).
In addition, you can use standard R indexing to access values, or to
replace values (assign new values to cells) in a terra
object. If
you replace a value in a terra
object based on a file, the
connection to that file is lost (because it now is different from that
file). Setting raster values for very large files will be very slow with
this approach as each time a new (temporary) file, with all the values,
is written to disk. If you want to overwrite values in an existing file,
you can use update
(with caution!)
#r[cells]
#r[1:4]
#sources(r)
#r[2:3] <- 10
#r[1:4]
#sources(r)
Note that in the above examples values are retrieved using cell numbers. That is, a raster is represented as a (one-dimensional) vector. Values can also be inspected using a (two-dimensional) matrix notation. As for R matrices, the first index represents the row number, the second the column number.
#r[1]
#r[2,2]
#r[1,]
#r[,2]
#r[1:3,1:3]
# keep the matrix structure
#r[1:3,1:3, drop=FALSE]
Accessing values through this type of indexing should be avoided inside
functions as it is less efficient than accessing values via functions
like values
.