The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Cell Operations

library(vaster)

Overview

Cell operations are at the heart of raster grid logic. This vignette covers:

All functions use the standard vaster convention: dimension is c(ncol, nrow) and extent is c(xmin, xmax, ymin, ymax).

Cell Indexing

Cells are numbered starting from 1 at the top-left corner, proceeding row-wise (left-to-right, then top-to-bottom):

 1  2  3  4
 5  6  7  8
 9 10 11 12
## define a simple 4x3 grid
dimension <- c(4, 3)   # 4 columns, 3 rows
extent <- c(0, 4, 0, 3) # xmin=0, xmax=4, ymin=0, ymax=3

n_cell(dimension)
#> [1] 12
n_col(dimension)
#> [1] 4
n_row(dimension)
#> [1] 3

Cells ↔︎ Coordinates

From cells to coordinates

Use xy_from_cell() to get the centre coordinates of cells:

## single cell
xy_from_cell(dimension, extent, 1)
#>      [,1] [,2]
#> [1,]  0.5  2.5

## multiple cells
xy_from_cell(dimension, extent, c(1, 4, 9, 12))
#>      [,1] [,2]
#> [1,]  0.5  2.5
#> [2,]  3.5  2.5
#> [3,]  0.5  0.5
#> [4,]  3.5  0.5

## all cells
xy_from_cell(dimension, extent, seq_len(n_cell(dimension)))
#>       [,1] [,2]
#>  [1,]  0.5  2.5
#>  [2,]  1.5  2.5
#>  [3,]  2.5  2.5
#>  [4,]  3.5  2.5
#>  [5,]  0.5  1.5
#>  [6,]  1.5  1.5
#>  [7,]  2.5  1.5
#>  [8,]  3.5  1.5
#>  [9,]  0.5  0.5
#> [10,]  1.5  0.5
#> [11,]  2.5  0.5
#> [12,]  3.5  0.5

For just x or y coordinates:

x_from_cell(dimension, extent, 1:4)
#> [1] 0.5 1.5 2.5 3.5
y_from_cell(dimension, extent, c(1, 5, 9))
#> [1] 2.5 1.5 0.5

From coordinates to cells

Use cell_from_xy() to find which cell contains given coordinates:

## coordinates at cell centres
xy <- cbind(c(0.5, 1.5, 2.5), c(2.5, 1.5, 0.5))
cell_from_xy(dimension, extent, xy)
#> [1]  1  6 11

## coordinates outside the grid return NA
xy_outside <- cbind(c(-1, 5), c(1.5, 1.5))
cell_from_xy(dimension, extent, xy_outside)
#> [1] NA NA

## coordinates on cell boundaries go to the cell below/right
## except at the grid edge where they go to the last cell
xy_edge <- cbind(c(1.0, 4.0), c(2.0, 0.0))
cell_from_xy(dimension, extent, xy_edge)
#> [1]  6 12

Cells ↔︎ Row/Column

From cells to row/column

## get row and column for cells
rowcol_from_cell(dimension, extent, 1:12)
#>       row col
#>  [1,]   1   1
#>  [2,]   1   2
#>  [3,]   1   3
#>  [4,]   1   4
#>  [5,]   2   1
#>  [6,]   2   2
#>  [7,]   2   3
#>  [8,]   2   4
#>  [9,]   3   1
#> [10,]   3   2
#> [11,]   3   3
#> [12,]   3   4

For just row or column:

row_from_cell(dimension, 1:12)
#>  [1] 1 1 1 1 2 2 2 2 3 3 3 3
col_from_cell(dimension, 1:12)
#>  [1] 1 2 3 4 1 2 3 4 1 2 3 4

Note that row_from_cell() and col_from_cell() only need dimension since row/column positions don’t depend on extent.

From row/column to cells

Get cells for specific row/column combinations:

## single cell at row 2, column 3
cell_from_row_col(dimension, row = 2, col = 3)
#> [1] 7

## multiple cells (vectorized, with recycling)
cell_from_row_col(dimension, row = 1:3, col = 1:3)  # diagonal cells
#> [1]  1  6 11

Get all cells in specific rows or columns:

## all cells in row 2
cell_from_row(dimension, 2)
#> [1] 5 6 7 8

## all cells in column 3
cell_from_col(dimension, 3)
#> [1]  3  7 11

Get the cross-product of rows and columns (all combinations):

## all cells in rows 1-2 AND columns 2-3
cell_from_rowcol_combine(dimension, row = 1:2, col = 2:3)
#> [1] 2 3 6 7

Rows/Columns ↔︎ Coordinates

Convert directly between row/column indices and coordinates:

## x coordinate of each column (centre)
x_from_col(dimension, extent, 1:4)
#> [1] 0.5 1.5 2.5 3.5

## y coordinate of each row (centre)
y_from_row(dimension, extent, 1:3)
#> [1] 2.5 1.5 0.5

## which column contains this x coordinate
col_from_x(dimension, extent, c(0.5, 2.5, 3.9))
#> [1] 1 3 4

## which row contains this y coordinate
row_from_y(dimension, extent, c(2.5, 1.5, 0.1))
#> [1] 1 2 3

Cells ↔︎ Extents

Extent from cells

Get the bounding box that covers a set of cells:

## extent of a single cell
extent_from_cell(dimension, extent, 1)
#> [1] 0 1 2 3

## extent covering multiple cells
extent_from_cell(dimension, extent, c(1, 4))  # top row
#> [1] 0 4 2 3
extent_from_cell(dimension, extent, c(1, 12)) # full grid
#> [1] 0 4 0 3

Cells from extent

Find all cells within a given extent:

## cells within a sub-extent
sub_extent <- c(1, 3, 1, 2)  # xmin=1, xmax=3, ymin=1, ymax=2
cell_from_extent(dimension, extent, sub_extent)
#> [1] 6 7

The extent is automatically aligned to cell boundaries before finding cells.

Handling Invalid Inputs

Functions return NA for invalid inputs:

## invalid cell numbers
xy_from_cell(dimension, extent, c(0, 13, -1))
#>      [,1] [,2]
#> [1,]  3.5  3.5
#> [2,]  0.5 -0.5
#> [3,]  2.5  3.5

## coordinates outside grid
cell_from_xy(dimension, extent, cbind(c(-1, 10), c(1, 1)))
#> [1] NA NA

## invalid row/column
cell_from_row_col(dimension, row = 0, col = 1)
#> [1] NA
cell_from_row_col(dimension, row = 4, col = 1)  # only 3 rows exist
#> [1] NA

Practical Example: Sampling Grid Points

Create a stratified sample by selecting one random point from each cell:

set.seed(42)
dimension <- c(5, 4)
extent <- c(0, 10, 0, 8)

## get cell centres
centres <- xy_from_cell(dimension, extent, seq_len(n_cell(dimension)))

## add random jitter within each cell
res <- c(x_res(dimension, extent), y_res(dimension, extent))
jitter_x <- runif(n_cell(dimension), -res[1]/2, res[1]/2)
jitter_y <- runif(n_cell(dimension), -res[2]/2, res[2]/2)

sample_points <- cbind(
  x = centres[, 1] + jitter_x,
  y = centres[, 2] + jitter_y
)

head(sample_points)
#>             x        y
#> [1,] 1.829612 7.808063
#> [2,] 3.874151 6.277420
#> [3,] 4.572279 7.977783
#> [4,] 7.660895 7.893336
#> [5,] 9.283491 6.164875
#> [6,] 1.038192 5.028424

## verify all points fall in expected cells
all(cell_from_xy(dimension, extent, sample_points) == seq_len(n_cell(dimension)))
#> [1] TRUE

See Also

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.