knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  echo = FALSE
)
suppressPackageStartupMessages(library(dplyr))
library(ggplot2)
library(PACTA.analysis)

``` {r functions} tdm_demo_plot<- function(data) { data %>% ggplot(aes(x = year, y = production, group = type)) + geom_line(aes(color = type, linetype = linetype)) + geom_point(aes(shape = type)) + labs(title = "Production by Year", x = "Year", y = "Production") + guides(linetype = "none") + guides(fill = "none") }

# Introduction 

There are several metrics included in the PACTA analysis. Some metrics offer
interesting insights on short time-scales (e.g. five years into the future).
However, analysts may also be interested in longer-term insights (e.g. 10+ years
into the future). To address this, we propose here the Transition Disruption
Metric. In this article, we will motivate why such a metric is necessary, define
the metric, provide a brief derivation, and explore interesting regions of the
metric function, along with their interpretation.

# Motivation

PACTA offers many metrics. One key component of most of these metrics if
forward-looking data. This forward-looking data estimates the production of
physical assets and is usually able to reliably forecast data to about five
years into the future.

Another key component of these metrics is a climate scenario. These scenarios
project how production *should* shift to mediate climate change. Most of these
scenarios project that production should shift relatively smoothly from
high-carbon to low-carbon technologies. There are, however, certain climate
scenarios which shift very abruptly, often quite late in the scenario timeline
(sometimes 20+ years into the future). These so-called "delayed response"
scenarios, such as the Inevitable Policy Response (IPR) scenario, assume that
future production of most sectors follow current trends (i.e. business as
usual), before inevitably resulting in a massive and disruptive transition to
low-carbon technologies in the long-term.

A possible use-case of these "delayed response" scenarios is to estimate the
risks associated with a worst-case scenario materializing. In other words, we
might want to measure how **disruptive** a climate **transition** could be to a
company or portfolio. Now, since the interesting part of these delayed response
scenarios is often positioned well beyond the five year time-horizon of our
forward-looking data, most other PACTA metrics (e.g. Volume Trajectory) don't
provide useful insights into the later years of the scenario. 

We propose the **Transition Disruption Metric** (TDM) as a way to address this
problem. This metric aims to provide useful insights in the medium- to long-
term (i.e. time-horizons greater than five years).

# Metric Definition

First, let us define the metric with no context. We will then derive it together
in the following section. The Transition Disruption Metric, $TDM$, for some
technology, $i$ is:

$$TDM_i = max\left(0, \frac{S_i (t+t_2) - P_i(t+t_1)}{S_i(t+t_2) - S_i(t)} * \left(\frac{t_2}{t_2-t_1}\right)\right) $$

where:
- $i$ is some technology 

- $t$ is some year - 

- $S_i(t)$ is a climate scenario, forecasting production for some technology
$i$, at year $t$

- $P_i(t)$ is the production associated to a company or portfolio, for some
technology $i$, at year $t$

- $t_1$ and $t_2$ are two future years, where $t_1 < t_2$

# Derivation

Let's derive this metric together. Consider first some arbitrary function,
$S(t)$, that in general may increase or decrease over time. This function could
represent, for example, a climate scenario dictating how production must change
to mitigate climate change:

```r

data <- tibble::tribble(
  ~production, ~year,  ~type, ~linetype,
           1L, 2020L, "S(t)",   "solid",
           2L, 2025L, "S(t)",   "solid",
           3L, 2030L, "S(t)",   "solid",
           4L, 2035L, "S(t)",   "solid",
           5L, 2040L, "S(t)",   "solid",
           6L, 2045L, "S(t)",   "solid",
           7L, 2050L, "S(t)",   "solid"
  )

data %>%
  filter(type == "S(t)") %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#CC6666", "#9999CC")) +
  scale_shape_manual(values = c("circle", "triangle")) +
  theme(
    axis.text.x = element_blank(),
    axis.text.y = element_blank()
  )

Now, let's say we know the production associated with a company or portfolio, $P(t)$, for the range $(t,t + t_1)$. In general, $t + t_1$ will be less than the end year of the scenario:

data <- tibble::tribble(
  ~production, ~year,  ~type, ~linetype,
            1, 2020L, "S(t)",   "solid",
            2, 2025L, "S(t)",   "solid",
            3, 2030L, "S(t)",   "solid",
            4, 2035L, "S(t)",   "solid",
            5, 2040L, "S(t)",   "solid",
            6, 2045L, "S(t)",   "solid",
            7, 2050L, "S(t)",   "solid",
          0.5, 2020L, "P(t)",   "solid",
            1, 2025L, "P(t)",   "solid"
  )


data %>%
  tdm_demo_plot() + 
  scale_color_manual(values = c("#9999CC", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "circle")) +
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "", "", "", "", "")
  )

We are comparing the estimated future production of a portfolio against what the scenario is suggesting. We can thus define a "transition", simply as adjusting the portfolio's production to match that of the scenario.

If we want to determine how disrupted a portfolio might be between the last date we have data for it, $t+t_1$, and some future date in the scenario, $t+t_2$, we may simply draw a line connecting the two points:

data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            1, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            3, 2030L,               "S(t)",   "solid",
            4, 2035L,               "S(t)",   "solid",
            5, 2040L,               "S(t)",   "solid",
            6, 2045L,               "S(t)",   "solid",
            7, 2050L,               "S(t)",   "solid",
          0.5, 2020L,               "P(t)",   "solid",
            1, 2025L,               "P(t)",   "solid",
            1, 2025L, "Required build-out",  "dashed",
            3, 2030L, "Required build-out",  "dashed"
  )


data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )

Suppose now we wish to compare the slope of the scenario, $m_S$ and the slope of the required future build-out of the portfolio, $m_P$ (that is, the slope of the dashed line in the above plot).

The slope of the scenario, between $(t, t+t2)$ is:

$$ m_S = \frac{S(t+t_2) - S(t)}{(t+t_2) - (t)} $$

To calculate the slope of the portfolio's required build-out, recall that we have constructed this line to connect $P(t+t_1)$ and $S(t+t_2)$. Thus we can see that the slope will be:

$$ m_P = \frac{S(t+t_2) - P(t+t_1)}{(t+t_2) - (t+t_1)}$$

Taking the ratio of these two slopes, and tidying up a bit, yields:

$$\frac{m_P}{m_S} = \frac{S_i (t+t_2) - P_i(t+t_1)}{S_i(t+t_2) - S_i(t)} * \left(\frac{t_2}{t_2-t_1}\right)$$ This looks similar to the metric we defined at the beginning, but we aren't quite done yet. Let's analyze some interesting regions of this function, and try to understand what is missing.

Interesting regions

Increasing Scenarios

For now, let's assume that $m_S$ is strictly positive, thus the scenario is increasing. We will explore the opposite case later.

data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            1, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            3, 2030L,               "S(t)",   "solid",
            4, 2035L,               "S(t)",   "solid",
            5, 2040L,               "S(t)",   "solid",
            6, 2045L,               "S(t)",   "solid",
            7, 2050L,               "S(t)",   "solid",
          0.5, 2020L,               "P(t)",   "solid",
          0.6, 2025L,               "P(t)",   "solid",
          0.6, 2025L, "Required build-out",  "dashed",
            3, 2030L, "Required build-out",  "dashed"
  )


data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )
data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            1, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            3, 2030L,               "S(t)",   "solid",
            4, 2035L,               "S(t)",   "solid",
            5, 2040L,               "S(t)",   "solid",
            6, 2045L,               "S(t)",   "solid",
            7, 2050L,               "S(t)",   "solid",
          0.5, 2020L,               "P(t)",   "solid",
            2, 2025L,               "P(t)",   "solid",
            2, 2025L, "Required build-out",  "dashed",
            3, 2030L, "Required build-out",  "dashed"
  )

data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )
data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            1, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            3, 2030L,               "S(t)",   "solid",
            4, 2035L,               "S(t)",   "solid",
            5, 2040L,               "S(t)",   "solid",
            6, 2045L,               "S(t)",   "solid",
            7, 2050L,               "S(t)",   "solid",
          0.5, 2020L,               "P(t)",   "solid",
          2.5, 2025L,               "P(t)",   "solid",
          2.5, 2025L, "Required build-out",  "dashed",
            3, 2030L, "Required build-out",  "dashed"
  )

data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )
data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            1, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            3, 2030L,               "S(t)",   "solid",
            4, 2035L,               "S(t)",   "solid",
            5, 2040L,               "S(t)",   "solid",
            6, 2045L,               "S(t)",   "solid",
            7, 2050L,               "S(t)",   "solid",
          0.5, 2020L,               "P(t)",   "solid",
            4, 2025L,               "P(t)",   "solid",
            4, 2025L, "Required build-out",  "dashed",
            3, 2030L, "Required build-out",  "dashed"
  )

data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )

In this final case, we don't necessarily need a metric as we don't expect the portfolio to be disrupted if it is already out-performing against the scenario, so we can attenuate negative values:

$$max\left(0, \frac{m_P}{m_S}\right)$$

or

$$max\left(0, \frac{S_i (t+t_2) - P_i(t+t_1)}{S_i(t+t_2) - S_i(t)} * \left(\frac{t_2}{t_2-t_1}\right)\right)$$ This is exactly the metric we defined at the start.

Decreasing Scenarios

To be complete, let's consider decreasing scenarios (i.e scenarios where $m_S < 0$). For such a scenario, the above cases still hold their validity, just with the sign of $m_P$ reversed. That is to say:

data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            7, 2020L,               "S(t)",    "solid",
            6, 2025L,               "S(t)",    "solid",
            5, 2030L,               "S(t)",    "solid",
            4, 2035L,               "S(t)",    "solid",
            3, 2040L,               "S(t)",    "solid",
            2, 2045L,               "S(t)",    "solid",
            1, 2050L,               "S(t)",    "solid",
            7, 2020L,               "P(t)",    "solid",
            7, 2025L,               "P(t)",    "solid",
            7, 2025L, "Required build-out",   "dashed",
            5, 2030L, "Required build-out",   "dashed"
  )

data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
    )

It is left as an exercise to the reader to prove that, due to similar sign cancellations, Cases 2, 3 and 4 keep their interpretation, regardless of if the scenario increases or decreases.

Non-Monotonic Scenario

There is one final situation we have not yet accounted for, and this is the case of the non-monotonic scenario. Consider the situation that $S(t)$ increases (or decreases) over the period $(t, t+t_2)$, but then decreases (or increases) over the following time-period:

data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            3, 2020L,               "S(t)",    "solid",
            2, 2025L,               "S(t)",    "solid",
            1, 2030L,               "S(t)",    "solid",
            2, 2035L,               "S(t)",    "solid",
            3, 2040L,               "S(t)",    "solid",
            4, 2045L,               "S(t)",    "solid",
            5, 2050L,               "S(t)",    "solid"
  )

data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#CC6666")) +
  scale_linetype_manual(values = c("solid")) + 
  scale_shape_manual(values = c("circle")) +
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
  )

Here, our usual formulation might look something like this:

data <- tibble::tribble(
  ~production, ~year,                ~type, ~linetype,
            3, 2020L,               "S(t)",   "solid",
            2, 2025L,               "S(t)",   "solid",
            1, 2030L,               "S(t)",   "solid",
            2, 2035L,               "S(t)",   "solid",
            3, 2040L,               "S(t)",   "solid",
            4, 2045L,               "S(t)",   "solid",
            5, 2050L,               "S(t)",   "solid",
            3, 2020L,               "P(t)",   "solid",
          2.9, 2025L,               "P(t)",   "solid",
          2.9, 2025L, "Required build-out",  "dashed",
            1, 2030L, "Required build-out",  "dashed"
  )


data %>%
  tdm_demo_plot() +
  scale_color_manual(values = c("#9999CC", "#0B7A75", "#CC6666")) +
  scale_linetype_manual(values = c("dashed", "solid")) + 
  scale_shape_manual(values = c("triangle", "triangle", "circle")) +
  theme(
    axis.text.y = element_blank()
  ) + 
  scale_x_continuous(
    breaks = c(2020, 2025, 2030, 2035, 2040, 2045, 2050),
    labels = c("t", "t+t1", "t+t2", "", "", "", "")
  )

However this doesn't really make sense. Since overall the scenario is increasing, if the portfolio or company is producing more than the scenario projects it shouldn't be disrupted at all.

Normally, this would be accounted for by our $max(0, \frac{m_P}{m_S})$ function, however the function is now off by a factor of $-1$, since the scenario is changing directions.

To account for this, we add a special considerations to the $TDM$ metric:

IF $S(t+t_2) > S(t) > S(t+t_1)$ OR $S(t+t_2) < S(t) < S(t+t_1)$, then:

$$TDM = max(0, - \frac{m_P}{m_S})$$

ELSE:

$$TDM = max(0, \frac{m_P}{m_S})$$

Conclusion

We have derived together here the Transition Disruption Metric, which is useful for determining how a portfolio or company might be disrupted due to a delayed transition. We explored how different values of the metric can be interpreted, and how different edge-cases are handled.

TDM in Practice

One final note: in practice, PACTA's forward-looking data goes 5 years into the future, so we can set $t_1 = 5$. By default, we will measure the transition disruption against a total time horizon of 10 years, so $t_2 = 10$. In this case, this metric reduces to:

$$TDM_i = 2 * max\left(0, \frac{S_i (t+10) - P_i(t+5)}{S_i(t+10) - S_i(t)}\right)$$



2DegreesInvesting/PACTA_analysis documentation built on April 19, 2023, 6:42 p.m.