Title: | Indicators for the 'TILT' Project |
---|---|
Description: | Indicators for the 'TILT' project. |
Authors: | Mauro Lepore [aut, cre] , Tilman Trompke [aut], Linda Delacombaz [aut], Kalash Singhal [aut], Lyanne Ho [aut], 2 Degrees Investing Initiative [cph, fnd] |
Maintainer: | Mauro Lepore <[email protected]> |
License: | GPL (>= 3) |
Version: | 0.0.0.9201 |
Built: | 2024-11-01 04:40:48 UTC |
Source: | https://github.com/2DegreesInvesting/tiltIndicator |
The "emissions profile" measures the absolute GHG emissions of a product in comparison to a chosen benchmark of products. The assessment is first performed on a product-level and can then be aggregated to the company-level. The profile is expressed as the share of a company's products that are in a "high", "medium", or "low" emission profile category, based on the comparison to the benchmark. A higher emission profile indicates a larger impact on climate change compared to the benchmark and can therefore also be interpreted as one climate risk component to assess products, companies, or loan portfolios.
The "emission profile" is calculated in these steps:
The relative GHG emissions per product are collected from a Life-Cycle-Analysis (LCA) database by matching the products from our company dataset to the products from the LCA dataset.
All products are ranked according to their GHG emissions.
The products are grouped by the following benchmarks:
all
: All products.
isic_4digit
: All products within the same ISIC 4 digit code (example: 0112 Growing of rice).
tilt_sector
: All products within the same tilt sector (example: agriculture).
unit
: All products with the same unit (example: kg).
unit_isic_4digit
: All products with the same unit within the same ISIC 4 digit section (example: kg + 0112 Growing of rice).
unit_tilt_sector
: All products with the same unit within the same tilt sector (example: kg + agriculture).
For each benchmark, products are assigned to the emission profile category "low", "medium" or "high", depending on the GHG emissions arising from their production process in comparison to all other products within the same benchmark. For the assignment of the three categories, thresholds are used. Please find more information about the thresholds in the Thresholds section.
For the company-level results, we aggregate all products from the same category and benchmark and set them in relation to all products that the company produces. The company-level results are expressed as the company's share of products per category "low", "medium", and "high" in comparison to each benchmark.
The output of this indicator contains the following:
A column indicating the benchmark to which a product is compared.
A column indicating whether the product has "low", "medium" or "high" relative GHG emissions.
A column indicating the share of the products per category and benchmark".
emissions_profile(companies, co2, low_threshold = 1/3, high_threshold = 2/3)
emissions_profile(companies, co2, low_threshold = 1/3, high_threshold = 2/3)
companies , co2
|
A dataframe like the dataset with a matching name in tiltToyData (see Reference). |
low_threshold |
A numeric value to segment low and medium emission profile products. |
high_threshold |
A numeric value to segment medium and high emission profile products. |
A data frame with the column companies_id
, and the nested columnsproduct
and company
holding the outputs at product and company level. Unnesting product
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
. Unnesting company
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
, value
. Any column in the input datasets ending with *rowid
is also passed as is to the output at product level. The exception is any column named exactly rowid
– which is a reserved name and throws an error. Note this feature makes no sense at company level because potentially multiple rows in the input datasets are summarized into a single row in the output at company level.
Other main functions:
emissions_profile_upstream()
,
sector_profile_upstream()
,
sector_profile()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_emissions_profile_any_companies()) products <- read_csv(toy_emissions_profile_products_ecoinvent()) both <- emissions_profile(companies, products) both both |> unnest_product() both |> unnest_company()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_emissions_profile_any_companies()) products <- read_csv(toy_emissions_profile_products_ecoinvent()) both <- emissions_profile(companies, products) both both |> unnest_product() both |> unnest_company()
The indicator "emissions profile upstream" assesses the transition risk of the upstream products due to their relative carbon footprint to other upstream products. As a default option, each upstream product is compared to the carbon footprint of every other upstream product. Upstream products with a higher carbon footprint face a higher risk. On a company-level, the indicator proxies for the supply chain risk of a company - based on its inputs.
The indicator "emissions profile upstream" is therefore similar to the Product Carbon Transition Risk Indicator, but it focuses on the upstream products and not the product of the company. Upstream products are, for example, resources, packaging materials, energy and enabling services (such as tractor use on farm) to produce the product.
After identifying each carbon footprint for one upstream product, the input products are ranked according to their footprint. The ranking method is explained in the Thresholds section.
After assessing the upstream products' transition risk based on the carbon footprint of each product, they are aggregated at the company-level. We derive what percentage of the upstream products are high, medium and low transition risk.
This indicator consists of 2 broad steps:
Score upstream products: Identifying the upstream products for each product, and calculating the relative carbon footprint per upstream product.
Score companies: Aggregating on the company-level.
The sample data set includes inputs and co2 footprints for each product from Ecoinvent and sectors from Europages. NOTE: the following columns are a completely random selection and do not reflect the true information:
co2 footprints (not allowed to share licensed data right now)
sectors (as the matching with ecoinvent is not done yet, we do not have one sector per product yet)
emissions_profile_upstream( companies, co2, low_threshold = 1/3, high_threshold = 2/3 )
emissions_profile_upstream( companies, co2, low_threshold = 1/3, high_threshold = 2/3 )
companies , co2
|
A dataframe like the dataset with a matching name in tiltToyData (see Reference). |
low_threshold |
A numeric value to segment low and medium emission profile products. |
high_threshold |
A numeric value to segment medium and high emission profile products. |
A data frame with the column companies_id
, and the nested columnsproduct
and company
holding the outputs at product and company level. Unnesting product
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
. Unnesting company
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
, value
. Any column in the input datasets ending with *rowid
is also passed as is to the output at product level. The exception is any column named exactly rowid
– which is a reserved name and throws an error. Note this feature makes no sense at company level because potentially multiple rows in the input datasets are summarized into a single row in the output at company level.
Other main functions:
emissions_profile()
,
sector_profile_upstream()
,
sector_profile()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_emissions_profile_any_companies()) inputs <- read_csv(toy_emissions_profile_upstream_products_ecoinvent()) both <- emissions_profile_upstream(companies, inputs) both |> unnest_product() both |> unnest_company()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_emissions_profile_any_companies()) inputs <- read_csv(toy_emissions_profile_upstream_products_ecoinvent()) both <- emissions_profile_upstream(companies, inputs) both |> unnest_product() both |> unnest_company()
This function expands a range by adding noise to the left of the minimum values and to the right of the maximum values.
jitter_range(data, factor = 1, amount = NULL)
jitter_range(data, factor = 1, amount = NULL)
data |
A dataframe with columns |
factor |
numeric. |
amount |
numeric; if positive, used as amount (see below),
otherwise, if Default ( |
The input dataframe with the additional columns min_jitter
and
max_jitter
.
Other helpers:
summarize_range()
,
unnest_product()
library(tibble) set.seed(123) data <- tibble(min = -2:2, max = -1:3) data |> jitter_range(amount = 0.1) data |> jitter_range(amount = 2)
library(tibble) set.seed(123) data <- tibble(min = -2:2, max = -1:3) data |> jitter_range(amount = 0.1) data |> jitter_range(amount = 2)
The indicator "sector profile" measures the transition risk of products based on the sector's emissions targets the product belongs to. Those sector emission reduction targets vary across scenarios (e.g., net zero scenario or 1.5° scenario) and the time horizon (e.g., reduction needed in 2030, 2040, 2050 to achieve the targets).
After assessing each product, all the products with the same category are aggregated and set in relation to all products of the company. We, therefore, derive company-level information.
sector_profile( companies, scenarios, low_threshold = ifelse(scenarios$year == 2030, 1/9, 1/3), high_threshold = ifelse(scenarios$year == 2030, 2/9, 2/3) )
sector_profile( companies, scenarios, low_threshold = ifelse(scenarios$year == 2030, 1/9, 1/3), high_threshold = ifelse(scenarios$year == 2030, 2/9, 2/3) )
companies , scenarios
|
A dataframe like the dataset with a matching name in tiltToyData (see Reference). |
low_threshold |
A numeric value to segment low and medium reduction targets. |
high_threshold |
A numeric value to segment medium and high reduction targets. |
A data frame with the column companies_id
, and the nested columnsproduct
and company
holding the outputs at product and company level. Unnesting product
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
. Unnesting company
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
, value
. Any column in the input datasets ending with *rowid
is also passed as is to the output at product level. The exception is any column named exactly rowid
– which is a reserved name and throws an error. Note this feature makes no sense at company level because potentially multiple rows in the input datasets are summarized into a single row in the output at company level.
Other main functions:
emissions_profile_upstream()
,
emissions_profile()
,
sector_profile_upstream()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) both <- sector_profile(companies, scenarios) both both |> unnest_product() both |> unnest_company()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) both <- sector_profile(companies, scenarios) both both |> unnest_product() both |> unnest_company()
companies
Restructure "sector profile" companies
sector_profile_any_pivot_type_sector_subsector(data)
sector_profile_any_pivot_type_sector_subsector(data)
data |
A dataframe with these columns:
|
A companies
dataset as required by sector functions.
Other pre-processing helpers:
sector_profile_any_prepare_scenario()
,
sector_profile_any_prune_companies()
library(dplyr, warn.conflicts = FALSE) library(readr, warn.conflicts = FALSE) raw_companies <- example_raw_companies() glimpse(raw_companies) companies <- sector_profile_any_pivot_type_sector_subsector(raw_companies) companies
library(dplyr, warn.conflicts = FALSE) library(readr, warn.conflicts = FALSE) raw_companies <- example_raw_companies() glimpse(raw_companies) companies <- sector_profile_any_pivot_type_sector_subsector(raw_companies) companies
Polish output at company level
sector_profile_any_polish_output_at_company_level(data)
sector_profile_any_polish_output_at_company_level(data)
data |
The output of |
A dataframe.
library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) sector_profile(companies, scenarios) |> unnest_company() |> sector_profile_any_polish_output_at_company_level() companies_upstream <- read_csv(toy_sector_profile_upstream_companies()) inputs <- read_csv(toy_sector_profile_upstream_products()) sector_profile_upstream(companies_upstream, scenarios, inputs) |> unnest_company() |> sector_profile_any_polish_output_at_company_level()
library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) sector_profile(companies, scenarios) |> unnest_company() |> sector_profile_any_polish_output_at_company_level() companies_upstream <- read_csv(toy_sector_profile_upstream_companies()) inputs <- read_csv(toy_sector_profile_upstream_products()) sector_profile_upstream(companies_upstream, scenarios, inputs) |> unnest_company() |> sector_profile_any_polish_output_at_company_level()
scenarios
dataframeGiven a named list of scenarios returns a cleaner scenarios
dataframe
sector_profile_any_prepare_scenario(scenarios)
sector_profile_any_prepare_scenario(scenarios)
scenarios |
A named list of identically structured scenarios. |
A single, cleaner dataframe with an additional column to identify which rows come from which scenario.
Other pre-processing helpers:
sector_profile_any_pivot_type_sector_subsector()
,
sector_profile_any_prune_companies()
library(dplyr, warn.conflicts = FALSE) library(readr, warn.conflicts = FALSE) raw_weo <- example_raw_weo() raw_ipr <- example_raw_ipr() raw_scenarios <- list(weo = raw_weo, ipr = raw_ipr) sector_profile_any_prepare_scenario(raw_scenarios)
library(dplyr, warn.conflicts = FALSE) library(readr, warn.conflicts = FALSE) raw_weo <- example_raw_weo() raw_ipr <- example_raw_ipr() raw_scenarios <- list(weo = raw_weo, ipr = raw_ipr) sector_profile_any_prepare_scenario(raw_scenarios)
NA
& sector info is duplicatedFor each company, this function drops rows where the product information is missing and the sector information is duplicated.
sector_profile_any_prune_companies(data)
sector_profile_any_prune_companies(data)
data |
Typically a "sector profile" |
A dataframe with maybe fewer rows than the input data
.
Other pre-processing helpers:
sector_profile_any_pivot_type_sector_subsector()
,
sector_profile_any_prepare_scenario()
library(dplyr) # styler: off companies <- tribble( ~row, ~companies_id, ~clustered, ~activity_uuid_product_uuid, ~tilt_sector, 1L, "a", "b1", "c1", "x", 2L, "a", NA, NA, "x", 3L, "a", NA, NA, "y", 4L, "a", NA, NA, "y" ) # styler: off # Keep row 1: Has product info # Drop row 2: Lacks product info and sector info is duplicated # Keep row 3: Lacks product info but sector info is unique # Drop row 4: Lacks product info and sector info is duplicated companies sector_profile_any_prune_companies(companies)
library(dplyr) # styler: off companies <- tribble( ~row, ~companies_id, ~clustered, ~activity_uuid_product_uuid, ~tilt_sector, 1L, "a", "b1", "c1", "x", 2L, "a", NA, NA, "x", 3L, "a", NA, NA, "y", 4L, "a", NA, NA, "y" ) # styler: off # Keep row 1: Has product info # Drop row 2: Lacks product info and sector info is duplicated # Keep row 3: Lacks product info but sector info is unique # Drop row 4: Lacks product info and sector info is duplicated companies sector_profile_any_prune_companies(companies)
The indicator "sector profile upstream" assesses the transition risk of the input products based on the sector's emissions targets the input product belongs to. This indicator can be aggregated on company level and as such inform about the supply chain risk of an SME, based on its inputs' transition risk. The sector emission reduction targets vary across scenarios (e.g., net zero scenario or 1.5° scenario) and the time horizon (e.g., reduction needed in 2030, 2040, 2050 to achieve the targets). It, therefore, is similar to the Product Sector Risk Indicator but focuses on the input products that the company needs to produce its products.The input products are, for example, resources, packaging materials, energy and enabling services (such as tractor use on farm) to produce the product.
After identifying each carbon footprint for one input product, the input products are ranked according to their footprint. The ranking method is explained in the Thresholds section.
After assessing the input products for each product, they are aggregated at company-level to derive what percentage of the input products required by the company to produce its products have high, medium and low sector transition risk. We, therefore, derive the company-level information.
Please note that carbon emissions or emissions always mean CO2e.
sector_profile_upstream( companies, scenarios, inputs, low_threshold = ifelse(scenarios$year == 2030, 1/9, 1/3), high_threshold = ifelse(scenarios$year == 2030, 2/9, 2/3) )
sector_profile_upstream( companies, scenarios, inputs, low_threshold = ifelse(scenarios$year == 2030, 1/9, 1/3), high_threshold = ifelse(scenarios$year == 2030, 2/9, 2/3) )
companies , scenarios , inputs
|
A dataframe like the dataset with a matching name in tiltToyData (see Reference). |
low_threshold |
A numeric value to segment low and medium emission profile products. |
high_threshold |
A numeric value to segment medium and high emission profile products. |
A data frame with the column companies_id
, and the nested columnsproduct
and company
holding the outputs at product and company level. Unnesting product
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
. Unnesting company
yields a data frame with at least columns companies_id
, grouped_by
, risk_category
, value
. Any column in the input datasets ending with *rowid
is also passed as is to the output at product level. The exception is any column named exactly rowid
– which is a reserved name and throws an error. Note this feature makes no sense at company level because potentially multiple rows in the input datasets are summarized into a single row in the output at company level.
Other main functions:
emissions_profile_upstream()
,
emissions_profile()
,
sector_profile()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_upstream_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) inputs <- read_csv(toy_sector_profile_upstream_products()) both <- sector_profile_upstream(companies, scenarios, inputs) both both |> unnest_product() both |> unnest_company()
library(tiltIndicator) library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_upstream_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) inputs <- read_csv(toy_sector_profile_upstream_products()) both <- sector_profile_upstream(companies, scenarios, inputs) both both |> unnest_product() both |> unnest_company()
This function is a shortcut to dplyr::summarize(data, min = min(x), max = max(x))
.
summarize_range(data, col, .by = NULL)
summarize_range(data, col, .by = NULL)
data |
A dataframe. |
col |
Unquoted expression giving the name of a column in |
.by |
< |
A dataframe:
The rows come from the underlying groups.
The columns come from the grouping keys plus the new columns min
and
max
.
The groups are dropped.
Other helpers:
jitter_range()
,
unnest_product()
library(tibble) data <- tibble(x = 1:4, group = c(1, 1, 2, 2)) data summarize_range(data, x, .by = group)
library(tibble) data <- tibble(x = 1:4, group = c(1, 1, 2, 2)) data summarize_range(data, x, .by = group)
Unnest product- and company-level results
unnest_product(data) unnest_company(data)
unnest_product(data) unnest_company(data)
data |
A nested data frame, e.g. the output of |
A data frame.
Other helpers:
jitter_range()
,
summarize_range()
library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) both <- sector_profile(companies, scenarios) both both |> unnest_product() both |> unnest_company()
library(tiltToyData) library(readr) options(readr.show_col_types = FALSE) companies <- read_csv(toy_sector_profile_companies()) scenarios <- read_csv(toy_sector_profile_any_scenarios()) both <- sector_profile(companies, scenarios) both both |> unnest_product() both |> unnest_company()