In this example, we show which economic activities contribute most to greenhouse gas emissions in Belgium. We want to know how much an additional unit of production increases the CO₂-equivalent of various greenhouse gases, including methane (CH₄), nitrous oxide (N₂O), and fluorinated gases (e.g., chlorofluorocarbons, hydrochlorofluorocarbons, and halons).
While CO₂ is emitted in the greatest quantity, it is not the only
culprit for global warming, and fluorinated gases have a particularly
high potential to increase the greenhouse effect; therefore, in this
example, we will work with the combined CO₂-equivalent effect of all
greenhouse gases, abbreviated with GHG.
The following expression will import the symmetric input-output table
for Belgium (product-by-product, ESA 2010 transmission
naio_10_cp1700). The `stk_flow = “TOTAL”``makes clear that
we are not only considering effects in the domestic (Belgian) economy,
but imports, too, because TOTAL covers both domestic and imported
intermediate and final uses (ESA 2010 code TOTAL = DOM + IMP)
More about importing and working with matrices can be found in the articles (Introduction to iotables, Working with Eurostat Data.)
# For faster building this data can be loaded from "../extdata/environmental_impact_vignette.rda"
BE <- iotable_get(
source = "naio_10_cp1700",
geo = "BE",
year = 2020,
labelling = "short",
unit = "MIO_EUR",
stk_flow = "TOTAL"
)The following expression gets the the greenhouse gas emissions in CO₂
CO₂ equivalent thousand tons for Belgium in 2020. Under the hood, we
download the air emissions accounts from the Eurostat data warehouse.
Air Emissions Accounts (AEA), an official satellite account compiled
according to the SEEA-CF (System of Environmental-Economic
Accounting 2012: Central Framework), present data on air emissions
in a way that is fully compatible with the concepts, principles and data
of the national accounts, but needs further adjustment to input-output
tables, which is accomplished by airpol_get()
# For faster building this data has been loaded from "../extdata/environmental_impact_vignette.rda"
ghg <- airpol_get(
airpol = "GHG",
geo = "BE",
year = 2020,
unit = "THS_T"
)See ?airpol_get for the type of air pollutants that you
can add to a European standard SIOT. In this case, we will first use the
calculated CO₂-equivalent of mix of gases. We are calculating in
thousands of tons in this case (unit="THS_T").
Because we work with the naio_10_cp1700 matrix, which is
derived from product x product sources, the industry names of the SIOT
start with CPA.
The AEA uses NACE Rev. 2 (industry basis):
The following utility will adjust the supplementary data. This corresponds to the bridge matrix (B) defined in Eurostat Manual §15.4.2 that is used to transform industry-based extensions to product-based form.
You do not need to make this step if you work with
naio_10_cp1750 SIOT data, which is estimated from industry
x industry sources, and it uses NACE-like abbreviations.
The direct effects will show how many thousand tons of extra
greenhouse gases will be emitted per million euros of output at basic
prices (t CO₂-eq / million €) from Belgium’s industries. We are adding
with supplementary_add()—which wraps
rows_add()—the greenhouse gas vector in a conforming form
to inter-industry matrix of Belgium. We will only print the top five
emitters.
be_io <- BE %>%
supplementary_add(ghg_prod)
ghg_indicator <- input_indicator_create(
data_table = be_io,
input_row = "GHG_emission"
)
#> Columns and rows of CPA_T98, CPA_U are all zeros and will be removed.The greenhouse gas intensity indicator (direct emissions per unit of output):
# Only the top 5 is printed, rename, arrange and top_n are tidyverse functions:
ghg_indicator %>%
vector_transpose_longer(.keep = TRUE) %>%
rename(GHG_emission_indicator = .data$value) %>%
arrange(-.data$GHG_emission_indicator) %>%
top_n(5)
#> Warning: Use of .data in tidyselect expressions was deprecated in tidyselect 1.2.0.
#> ℹ Please use `"value"` instead of `.data$value`
#> This warning is displayed once per session.
#> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
#> generated.
#> Selecting by GHG_emission_indicator
#> # A tibble: 5 × 3
#> prod_na nace_r2 GHG_emission_indicator
#> <chr> <chr> <dbl>
#> 1 GHG_emission_indicator CPA_A01 1.13
#> 2 GHG_emission_indicator CPA_A03 1.05
#> 3 GHG_emission_indicator CPA_C23 1.04
#> 4 GHG_emission_indicator CPA_D 0.979
#> 5 GHG_emission_indicator CPA_H50 0.863In Belgium (based on the 2020 structure of the economy and considering 2020 emission levels) the most greenhouse gas intensive sectors are the usual suspects, but with a bit surprising top emitter.
| NACE code | Activity |
|---|---|
| A03 | Fishing and aquaculture |
| A01 | Crop and animal production, hunting and related service activities |
| H51 | Air transport |
| C23 | Manufacture of other non-metallic mineral products |
| D | Electricity, gas, steam and air conditioning supply |
This indicator shows only the direct greenhouse-gas emissions (CO₂, CH₄, N₂O and fluorinated gases) generated by each economic activity itself. It does not yet include the indirect emissions that occur along the value chain — the upstream supplier industries that provide intermediate inputs (backward linkages) or the downstream users that purchase and transform the outputs (forward linkages).
To capture the full environmental impact of final demand, these indirect effects are estimated using the Leontief inverse, which traces how additional demand for one product propagates through all interconnected industries.
The category Manufacture of other non-metallic mineral products requires some clarification. It covers a range of activities transforming mined or quarried non-metallic minerals — such as sand, gravel, stone, clay and refractory materials — by grinding, mixing, cutting, shaping or firing them into products for intermediate or final use. In practice, these are largely construction-related materials, so this sector reflects the environmental footprint of the building-products supply chain.
Let’s make a reality check, and calculate only with CO₂:
be_io_c <- BE %>%
supplementary_add(
co2 %>% convert_industry_to_product()
)
co2_indicator <- input_indicator_create(
data_table = be_io_c,
input_row = "CO2_emission"
)
#> Columns and rows of CPA_T98, CPA_U are all zeros and will be removed.
# Only the top 5 is printed:
co2_indicator %>%
vector_transpose_longer(.keep = TRUE) %>%
rename(CO2_emission_indicator = .data$value) %>%
arrange(-.data$CO2_emission_indicator) %>%
top_n(5)
#> Selecting by CO2_emission_indicator
#> # A tibble: 5 × 3
#> prod_na nace_r2 CO2_emission_indicator
#> <chr> <chr> <dbl>
#> 1 CO2_emission_indicator CPA_A03 1.04
#> 2 CO2_emission_indicator CPA_C23 1.03
#> 3 CO2_emission_indicator CPA_D 0.933
#> 4 CO2_emission_indicator CPA_H50 0.855
#> 5 CO2_emission_indicator CPA_C19 0.671Crop and animal production, hunting and related service activities falls out, and CPA_H50 Water transport comes back. Are those barges really so clean? And what happened with the agriculture?
Let’s check methane, which is a far more potent green house gas than CO₂.
be_io_m <- BE %>%
supplementary_add(
methane %>% convert_industry_to_product()
)
methane_indicator <- input_indicator_create(
data_table = be_io_m,
input_row = "CH4_emission"
)
#> Columns and rows of CPA_T98, CPA_U are all zeros and will be removed.
# Only the top 5 is printed:
methane_indicator %>%
vector_transpose_longer(.keep = TRUE) %>%
rename(CH4_emission_indicator = .data$value) %>%
arrange(-.data$CH4_emission_indicator) %>%
top_n(5)
#> Selecting by CH4_emission_indicator
#> # A tibble: 5 × 3
#> prod_na nace_r2 CH4_emission_indicator
#> <chr> <chr> <dbl>
#> 1 CH4_emission_indicator CPA_A01 0.0201
#> 2 CH4_emission_indicator CPA_E37-39 0.00311
#> 3 CH4_emission_indicator CPA_B 0.00157
#> 4 CH4_emission_indicator CPA_D 0.00134
#> 5 CH4_emission_indicator CPA_T 0.000470| NACE code | Activity |
|---|---|
| A01 | Crop and animal production, hunting and related service activities |
| E37-39 | Sewerage, waste management, remediation activities |
| D | Electricity, gas, steam and air conditioning supply |
| B | Mining and quarrying |
| A02 | Forestry and logging |
The appearance of Mining and quarrying is important, because it is the main input for the Manufacture of other non-metallic mineral products. Their effect may or may not be combined in Belgium, because the Belgian manufacturers can import mined or quarried products, too.
The multiplier considers these indirect effects, too. The top five polluters remain the same, but their ordering changes. Crop and animal production, hunting and related service activities goes ahead of Fishing and aquaculture—because methane is a more potent green house gas than CO₂. Cattle and sheep emit plenty of methane, and there are plenty of cattle and sheep in Belgium. The reason why it is important to consider these effects for each and every country, or, when possible, for regions, is that different countries produce different crops and animals. Producing poultry is far less problematic from a green house emission point of view than producing beef products.
As expected, the Manufacture of other non-metallic mineral products gets ahead of Air transport as it is highly interrelated with Mining and quarrying. Making building more sustainable would be a great achievement, but there is no really clear path: as we can see, Forestry and logging come with their problems, too.
I_be <- input_coefficient_matrix_create(
data_table = BE,
digits = 4
) %>%
leontief_inverse_create()
ghg_multipliers <- multiplier_create(
input_vector = ghg_indicator,
Im = I_be,
multiplier_name = "GHG_multiplier",
digits = 4
)
# Only the top 5 is printed:
ghg_multipliers %>%
vector_transpose_longer(.keep = TRUE) %>%
rename(GHG_multiplier = .data$value) %>%
arrange(-.data$GHG_multiplier) %>%
top_n(5)All analytical and extension functions used in this vignette were
validated against the official numerical examples published in
Beutel (2008), Eurostat Manual of Supply, Use and
Input–Output Tables (Luxembourg: Office for Official Publications
of the European Communities).
The table below lists the correspondence between each function and the
reference table reproduced during package testing.
cat(knitr::kable(
data.frame(
Function = c(
"input_coefficient_matrix_create()",
"leontief_matrix_create()",
"leontief_inverse_create()",
"supplementary_add()",
"input_indicator_create()",
"multiplier_create()"
),
Concept = c(
"Direct requirements (A)",
"Leontief matrix (I − A)",
"Total requirements (L = (I − A)⁻¹)",
"Environmental extension (CO₂, CH₄)",
"Input indicators (GVA, Compensation)",
"Total multipliers (GVA, Employment)"
),
Table = c("15.6", "15.9", "15.10", "15.13", "15.14", "15.16"),
Page = c("485", "487", "488", "494", "498", "503–504")
),
caption = "Cross-reference of package functions with Eurostat Manual (Beutel 2008)"
))Table: Cross-reference of package functions with Eurostat Manual (Beutel 2008) |Function |Concept |Table |Page | |:———————————|:————————————|:—–|:——-| |input_coefficient_matrix_create() |Direct requirements (A) |15.6 |485 | |leontief_matrix_create() |Leontief matrix (I − A) |15.9 |487 | |leontief_inverse_create() |Total requirements (L = (I − A)⁻¹) |15.10 |488 | |supplementary_add() |Environmental extension (CO₂, CH₄) |15.13 |494 | |input_indicator_create() |Input indicators (GVA, Compensation) |15.14 |498 | |multiplier_create() |Total multipliers (GVA, Employment) |15.16 |503–504 |
All functions were numerically cross-checked against the
corresponding Eurostat tables within rounding tolerance (< 1e-3),
confirming that the iotables analytical pipeline—
A → (I − A) → L → extensions → indicators →
multipliers—
faithfully reproduces the canonical Eurostat and UN SNA 2010
results.