Trace environmental extensions through the supply chain using the Leontief inverse, following the FABIO methodology (Bruckner et al., 2019). The footprint shows how much of an environmental pressure (e.g. land use, water, emissions) is embodied in the final consumption of each product in each country.
The multiplier matrix is computed as \(MP_{ij} = (e_i / X_i) \cdot L_{ij}\), where \(e_i\) is the extension for sector \(i\). For each demand category, the footprint is decomposed per target item using the FABIO diagonal approach: \(FP = MP \cdot \text{diag}(y)\), aggregated by item.
For large systems, pass z_mat and x_vec instead of
l_inv. This solves \((I - A) x = Y\) directly using a
sparse LU factorisation, avoiding the dense Leontief inverse
entirely and reducing memory from \(O(n^2)\) to
\(O(nnz)\).
Usage
compute_footprint(
l_inv = NULL,
x_vec,
y_mat,
extensions,
labels,
z_mat = NULL,
fd_labels = NULL,
output_tol = 1e-08,
value_added_floor = 0.001,
max_column_sum = 100,
conserve_extensions = TRUE,
report_conservation = FALSE
)Arguments
- l_inv
Leontief inverse matrix from
compute_leontief_inverse(). Ignored whenz_matis provided.- x_vec
Numeric vector of total output per sector.
- y_mat
Final demand matrix from
build_io_model().- extensions
Numeric vector of environmental extensions (e.g. hectares of land use) per sector. Must have the same length as
x_vec.- labels
Tibble with
area_codeanditem_cbs_codemapping row/column indices to their meaning. Frombuild_io_model().- z_mat
Optional inter-industry flow matrix from
build_io_model(). When provided, the system is solved directly (sparse LU), andl_invis not needed.- fd_labels
Optional tibble labelling Y columns. Pass
fd_labels[[i]]frombuild_io_model()output. When provided, footprints are decomposed per target item using the FABIO diagonal approach, and the result includes atarget_fdcolumn. When omitted, columns of Y are treated as sectors (appropriate only when Y is square).- output_tol
Minimum output considered valid when computing extension intensities. Sectors with
x_vec <= output_tolget zero intensity to avoid infinite or numerically explosive footprints from zero-output residuals.- value_added_floor
Minimum share of each sector's output that is treated as non-intermediate leakage when constructing A from
z_matifmax_column_sumis left at its low-level default. Ignored when a precomputedl_invis supplied withoutz_mat.- max_column_sum
Maximum allowed column sum in A when using
z_mat. Physical biomass systems can require more than one unit of intermediate input per unit of output, so the footprint path defaults to100and only clips extreme columns caused by residual inconsistencies or tiny outputs.- conserve_extensions
If
TRUE, rescale positive footprint flows within each origin area/item so their sum does not exceed the corresponding positive extension total. This keeps footprint outputs conservative when capped coefficients or negative final demand columns would otherwise make positive-only paths larger than the source extension.- report_conservation
If
TRUE, emit a message after computing the footprint reporting the conservation gap (the share of the direct extension that is not embodied in final demand), viacheck_footprint_conservation(). Off by default so the gap is opt-in but never silent when requested.
Value
A tibble with footprint results containing:
origin_area: Country where the pressure occurs.origin_polity_code: WHEP polity fororigin_area.origin_item: Item causing the pressure.target_area: Country consuming the product.target_polity_code: WHEP polity fortarget_area.target_item: Item consumed.target_fd: Demand category (e.g."food"). Only present whenfd_labelsis provided.value: Footprint value in extension units.
Examples
z_mat <- matrix(c(0, 5, 10, 0), nrow = 2)
x_vec <- c(100, 200)
l_inv <- compute_leontief_inverse(z_mat, x_vec)
#> Computing Leontief inverse (2x2 matrix)...
#> Inverting (I - A)...
#> ✔ Leontief inverse computed.
y_mat <- matrix(c(85, 195), ncol = 1)
extensions <- c(50, 30)
labels <- tibble::tibble(
area_code = c(1L, 1L),
item_cbs_code = c(1L, 2L)
)
# Small system: pass pre-computed L
compute_footprint(l_inv, x_vec, y_mat, extensions, labels)
#> ℹ Computing footprint for 2 sectors.
#> 2 sectors have non-zero extensions.
#> Final demand: 1 column.
#> Computing multiplier matrix...
#> Computing footprints...
#> ✔ Footprint complete: 2 non-zero flows.
#> # A tibble: 2 × 11
#> origin_area origin_polity_code origin_polity_name origin_polity_has_geometry
#> <int> <chr> <chr> <lgl>
#> 1 1 ARM-1991-2025 Armenia TRUE
#> 2 1 ARM-1991-2025 Armenia TRUE
#> # ℹ 7 more variables: origin_item <int>, target_area <int>,
#> # target_polity_code <chr>, target_polity_name <chr>,
#> # target_polity_has_geometry <lgl>, target_item <int>, value <dbl>
# Using Z directly (computes L internally)
compute_footprint(
x_vec = x_vec, y_mat = y_mat,
extensions = extensions, labels = labels,
z_mat = z_mat
)
#> ℹ Computing footprint for 2 sectors.
#> 2 sectors have non-zero extensions.
#> Final demand: 1 column.
#> Sparse solve path (no dense Leontief inverse).
#> Computing footprints...
#> ✔ Footprint complete: 2 non-zero flows.
#> # A tibble: 2 × 11
#> origin_area origin_polity_code origin_polity_name origin_polity_has_geometry
#> <int> <chr> <chr> <lgl>
#> 1 1 ARM-1991-2025 Armenia TRUE
#> 2 1 ARM-1991-2025 Armenia TRUE
#> # ℹ 7 more variables: origin_item <int>, target_area <int>,
#> # target_polity_code <chr>, target_polity_name <chr>,
#> # target_polity_has_geometry <lgl>, target_item <int>, value <dbl>
