-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Hy Nat!
Just came across a new bug this morning. The build_aggregation_table() fails with terra >= 1.9.0 (released 2026-03-07) due to a change in how terra::extract() returns results. The error occurs in calculate_pixel_fractions_single_polygon() at the line extract_wide[1, ], which assumes a 2D object (data.frame/matrix), but terra 1.9.x returns a vector instead.
The mbg DESCRIPTION currently lists terra in Imports with no version constraint, so terra 1.9.1 installs without warning and silently breaks this function.
Error
Error in `extract_wide[1, ]`:
! incorrect number of dimensionsTraceback
1. └─mbg::build_aggregation_table(...)
2. ├─data.table::rbindlist(...)
3. └─base::lapply(...)
4. └─mbg (local) FUN(X[[i]], ...)
5. └─mbg::calculate_pixel_fractions_single_polygon(...)
6. ├─data.table::data.table(...)
7. └─base::unlist(extract_wide[1, ])
Minimal Reproducible Example
library(terra) # 1.9.1
library(mbg)
library(sf)
# Any valid admin shapefile + matching population raster
adm2_sf <- st_read("path/to/admin2.shp")
pop_rast <- rast("path/to/population.tif")
# Build ID raster
primary_vect <- terra::vect(adm2_sf)
primary_vect$poly_id <- seq_len(nrow(primary_vect))
id_raster <- mbg::build_id_raster(
polygons = primary_vect,
template_raster = pop_rast
)
# This fails with terra >= 1.9.0
mbg::build_aggregation_table(
polygons = primary_vect,
id_raster = id_raster,
polygon_id_field = "poly_id",
verbose = TRUE
)Versions
- terra: 1.9.1 (fails) / 1.8-93 (works)
- mbg: 1.1.0
- R: 4.x
- OS: macOS
Root Cause
In calculate_pixel_fractions_single_polygon(), the line:
unlist(extract_wide[1, ])assumes extract_wide is a data.frame or matrix. In terra >= 1.9.0, the underlying extract() call returns a different structure (vector) for single-polygon extractions, causing the [1, ] row subsetting to fail.
Suggested Fixes
Option A — Fix the code to handle both return types:
if (!is.data.frame(extract_wide)) {
extract_wide <- as.data.frame(t(extract_wide))
}
unlist(extract_wide[1, ])Option B — Pin terra in DESCRIPTION until the code is updated:
Imports:
terra (< 1.9.0),
...
Workaround
My work around was to pin terra < 1.9.0 in my project (renv::install("terra@1.8-93")).
Happy to submit a PR if helpful.