geom_expressions: Geometry functions inside mutate(), filter(), and summarise()

geom_expressionsR Documentation

Geometry functions inside mutate(), filter(), and summarise()

Description

vectra recognizes a family of ⁠st_*⁠ geometry functions directly inside expression verbs. They run on the GEOS C library straight off the hex-WKB geometry column, one row at a time, with no per-batch round-trip through sf: tbl(f) |> filter(st_area(geometry) > 1e6) prunes the stream in C, and mutate(centroid = st_centroid(geometry)) adds a new hex-WKB geometry column. The computation is planar, in the geometry's own coordinate units, exactly as the streaming spatial verbs are.

Details

These names are interpreted by the expression engine; they are not exported R functions and are not called as such. They are available only inside mutate(), transmute(), filter(), and a grouped summarise() over a vectra_node. The geometry argument is the hex-WKB column (named geometry by convention). A function that returns a geometry produces another hex-WKB column; materialize it with collect_sf() (point it at the column with ⁠geom =⁠), or write it with write_tiff()/sf::st_write().

Measures (return a number)

st_area(g)

Area of polygonal geometry (0 for lines and points).

st_length(g), st_perimeter(g)

Length of a line, or the perimeter (boundary length) of a polygon. The two names are aliases.

st_x(g), st_y(g)

Coordinate of a point geometry; NA for a non-point.

st_npoints(g)

Number of coordinates in the geometry.

st_ngeometries(g)

Number of sub-geometries in a collection or multi-geometry (1 for a single geometry).

st_distance(a, b)

Shortest planar distance between two geometries (see the binary second argument below).

Predicates (return TRUE / FALSE)

Unary: st_is_valid(g), st_is_empty(g), st_is_simple(g).

Binary topological relations, each taking a second geometry: st_intersects, st_within, st_contains, st_overlaps, st_touches, st_crosses, st_equals, st_disjoint, st_covers, st_covered_by. Used in filter() they keep the rows where the relation holds.

Type (returns a string)

st_geometry_type(g) gives the GEOS geometry type name ("Point", "Polygon", "MultiPolygon", ...).

Transforms (return a geometry)

st_centroid(g)

Area (or length, or vertex) centroid.

st_point_on_surface(g)

A point guaranteed to lie on the geometry.

st_boundary(g)

The topological boundary.

st_envelope(g)

The axis-aligned bounding rectangle.

st_convex_hull(g)

The convex hull.

st_make_valid(g)

Repair an invalid geometry.

st_buffer(g, dist)

Buffer by dist (round joins, 8 segments per quadrant).

st_simplify(g, tol)

Topology-preserving Douglas-Peucker simplification with tolerance tol.

The second geometry of a binary op

For st_distance and the binary predicates, the second argument can be another geometry column (compared row by row), a constant sf/sfc object (a multi-feature object is unioned to one geometry), or a hex-WKB string. A constant is parsed once and reused across every row, so testing a whole stream against one area of interest stays cheap.

Missing geometry

A missing (NA) or unparseable geometry, or an operation that has no answer (a coordinate of a non-point, distance to a missing geometry), yields NA for that row rather than an error.

See Also

mutate(), filter(), collect_sf() to materialize a geometry result as sf; spatial_map() for an arbitrary per-feature sf transform; spatial_filter() and spatial_join() for relating a stream to a resident reference layer.

Examples

if (requireNamespace("sf", quietly = TRUE)) {
  nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
  f <- tempfile(fileext = ".vtr")
  write_vtr(data.frame(
    NAME     = nc$NAME,
    geometry = sf::st_as_binary(sf::st_geometry(nc), hex = TRUE)
  ), f)

  # measures: add area and perimeter columns
  tbl(f) |>
    mutate(area = st_area(geometry), perim = st_perimeter(geometry)) |>
    select(NAME, area, perim) |>
    collect() |>
    head()

  # predicate: keep counties intersecting an area of interest
  aoi <- sf::st_as_sfc(sf::st_bbox(
    c(xmin = -81.5, ymin = 36.2, xmax = -80.5, ymax = 36.6)))
  tbl(f) |> filter(st_intersects(geometry, aoi)) |> collect() |> nrow()

  # transform: replace each county with its centroid, materialize as sf
  tbl(f) |>
    mutate(geometry = st_centroid(geometry)) |>
    select(NAME, geometry) |>
    collect_sf()

  unlink(f)
}

vectra documentation built on July 10, 2026, 5:08 p.m.