luh2impact

luh2impact turns raw land use data into the parameters read by IFPRI's IMPACT model and its LUMEN land use downscaler. It holds two independent pipelines that share a country definition — the IMPACT regions shapefile and Sets.xlsx — but nothing else:

Both use the same six land pools: crop, past, natfor (naturally regenerating forest), plant (planted forest), other and urban. Protected area is deliberately not a pool — it overlays natfor, past and other — and is carried as a separate area floor.

Installation

From the IFPRI r-universe:

install.packages(
    "luh2impact",
    repos = c("https://ifpri.r-universe.dev", "https://cloud.r-project.org")
)

Or straight from GitHub:

# install.packages("remotes")
remotes::install_github("IFPRI/luh2impact")

The package depends on DOORMAT for reading GDX files, which is installed from GitHub rather than CRAN.

GDX support

Every function that reads or writes a GDX file needs gamstransfer, which ships with GAMS rather than CRAN, so it is only a Suggests. Install it from your GAMS system directory:

install.packages("<GAMS_DIR>/apifiles/R/gamstransfer", repos = NULL, type = "source")

Without it, the package still installs and loads; the GDX entry points will not run.

Pixel pipeline: LUH2 to LUMEN

library(luh2impact)

# One-off: rasterize WDPA protected areas onto the LUH2 grid (slow)
wdpa_process(
    gdb_path   = "data/WDPA/WDPA_Jul2026_Public.gdb",
    static_nc  = "data/LUH2/staticData_quarterdeg.nc",
    output_tif = "data/WDPA/pa_area_km2.tif",
    year       = 2021
)

luh2gdx(
    states_nc   = "data/LUH2/states.nc",
    static_nc   = "data/LUH2/staticData_quarterdeg.nc",
    planted_tif = "data/SDPT/sdpt_global.tif",
    cty_shp     = "data/IMPACT/impact_regions.shp",
    impact_gdx  = "data/IMPACT/solution.gdx",
    output_gdx  = "outputs/lumen_input.gdx",
    year        = 2021,
    pa_tif      = "data/WDPA/pa_area_km2.tif"
)

luh2gdx() chains luh2_load(), luh2_pool_trend(), luh2_extract_year(), luh2_merge_planted(), luh2_suitability(), luh2_build_pixels() and luh2_export_gdx(). Every one of them is exported, so the pipeline can be run step by step when only part of it needs redoing.

Pixel areas are reconciled to the IMPACT country totals by iterative proportional fitting, and the allocation weights combine each pool's historical trend with a long-run suitability index.

After LUMEN solves:

luh2_write_tifs("outputs/CHM/solution_lu.gdx", "outputs/CHM")
luh2_plot_results("outputs/CHM", "data/IMPACT/impact_regions.shp")
luh2_plot_bii("outputs/CHM", "data/IMPACT/impact_regions.shp")

Country pipeline: FAOSTAT to IMPACT

luh2_landuse_elasticities(
    fao_land_csv        = "data/FAOSTAT/Inputs_LandUse_E_All_Data_(Normalized).csv",
    sets_xlsx           = "data/IMPACT/Sets.xlsx",
    ssp_gdx             = "data/SSP/ssp.gdx",
    fao_country_map_csv = "data/FAOSTAT/country_codes.csv",
    wb_gdppc_csv        = "data/WorldBank/API_NY.GDP.PCAP.PP.CD.csv",
    output_gdx          = "outputs/landuse.gdx",
    states_nc           = "data/LUH2/states.nc",   # adds urban land
    static_nc           = "data/LUH2/staticData_quarterdeg.nc",
    cty_shp             = "data/IMPACT/impact_regions.shp",
    pa_tif              = "data/WDPA/pa_area_km2.tif"  # adds LANDPA00
)

The elasticity core (luh2_load_faoland() → luh2_compute_gdppc() → luh2_fit_elasticities() → luh2_export_elasticities_gdx()) always runs; urban land and protected area are added only when their inputs are supplied. BII coefficients are always written, either blended from FAOSTAT primary forest shares (luh2_bii_coeff_cty()) or read from the pixel-derived tables shipped with the package (luh2_bii_coeff_cty_pixel()).

The fitted model, per country and per non-cropland pool, is

dln_use ~ dln_crop + dln_gdppc

on first-differenced logs of annual FAOSTAT areas. The coefficients are descriptive associations within a country's own history, estimated without controls or instruments; they are not causal effects. Countries that cannot be fitted are kept and flagged rather than dropped, and only ok rows reach the LANDELAS parameter the model solves with.

Input data

Nothing ships with the package except the pre-computed pixel BII tables under inst/extdata; every entry point takes file paths.

Input Used by Source
states.nc, staticData_quarterdeg.nc both LUH2
Planted forest GeoTIFF pixel e.g. SDPT
WDPA geodatabase both UNEP-WCMC / IUCN
IMPACT regions shapefile (NEW_REGION field) both IMPACT
Sets.xlsx (Regions sheet) country IMPACT
IMPACT solution GDX (LANDX0) pixel IMPACT
Inputs_LandUse_E_All_Data_(Normalized).csv country FAOSTAT
SSP scenario GDX (OECD_GDP, POP) country SSP database
NY.GDP.PCAP.PP.CD CSV country World Bank

Known limitations

Documentation

?luh2impact gives the package overview; every exported function has its own help page, and the two pipelines are cross-linked through the pixel pipeline functions and country pipeline functions families.

License

CC BY 4.0. See LICENSE.md.