Problem
dft_rast_transition() silently produces wrong results when passed raw integer rasters that weren't classified via dft_rast_classify(). The code_lookup maps integer codes to class names using the default class table, so:
- If codes happen to match (e.g., IO LULC codes), results look correct but the user never explicitly classified
- If codes don't match (custom rasters, climate data, habitat types), class names are
NA with no error
As drift generalizes beyond land cover (climate zones, habitat classification, soil types, any categorical raster), this becomes more likely. A user with a pre-classified raster from another source has no reason to run dft_rast_classify() first.
Proposed Solution
Two complementary changes:
-
Validate input is factor: If the input SpatRasters are not factor rasters, warn or error with a message pointing to dft_rast_classify() or explaining how to set factors manually via terra::set.cats().
-
Read labels from the raster itself: Factor rasters already carry their class labels. Instead of requiring a class_table to decode integers, read the factor levels directly when available. Fall back to class_table only for raw integer rasters. This makes the function work with any pre-classified categorical raster regardless of source.
Option 2 is the bigger unlock — it means dft_rast_transition() works out of the box with any factor raster, not just drift-classified ones. A user with climate zone rasters from another package could compute transitions directly.
Context
Discovered during code review of #14. The current code works because the test data and typical pipeline always use IO LULC codes with the matching default class table. The gap only surfaces with non-standard inputs.
Problem
dft_rast_transition()silently produces wrong results when passed raw integer rasters that weren't classified viadft_rast_classify(). Thecode_lookupmaps integer codes to class names using the default class table, so:NAwith no errorAs drift generalizes beyond land cover (climate zones, habitat classification, soil types, any categorical raster), this becomes more likely. A user with a pre-classified raster from another source has no reason to run
dft_rast_classify()first.Proposed Solution
Two complementary changes:
Validate input is factor: If the input SpatRasters are not factor rasters, warn or error with a message pointing to
dft_rast_classify()or explaining how to set factors manually viaterra::set.cats().Read labels from the raster itself: Factor rasters already carry their class labels. Instead of requiring a
class_tableto decode integers, read the factor levels directly when available. Fall back toclass_tableonly for raw integer rasters. This makes the function work with any pre-classified categorical raster regardless of source.Option 2 is the bigger unlock — it means
dft_rast_transition()works out of the box with any factor raster, not just drift-classified ones. A user with climate zone rasters from another package could compute transitions directly.Context
Discovered during code review of #14. The current code works because the test data and typical pipeline always use IO LULC codes with the matching default class table. The gap only surfaces with non-standard inputs.