knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(dplyr) library(Recca) library(magrittr) library(matsbyname) library(matsindf) library(tidyr)
```{=tex} \newcommand{\transpose}[1]{#1^\mathrm{T}} \newcommand{\inverse}[1]{#1^{\mathrm{-}1}} \newcommand{\mat}[1]{\mathbf{#1}} \newcommand{\colvec}[1]{\mathbf{#1}} \newcommand{\rowvec}[1]{\transpose{\colvec{#1}}} \newcommand{\inversetranspose}[1]{\transpose{\left( \inverse{\mat{#1}} \right)}} \newcommand{\transposeinverse}[1]{\inverse{\left( \transpose{\mat{#1}} \right)}} \newcommand{\hatinv}[1]{\inverse{\widehat{#1}}}
## Introduction `Recca` is an `R` package that builds upon input-output (I-O) analysis, developed originally to analyze money flow through economies, to analyze energy conversion chains (ECCs). Historically, input-output (I-O) analysis has been used to analyze "what-if" scenarios involving changes to the production structure of an economy. A common scenario asks "how will the structure of intermediate industries (represented by $\mathbf{U}$ and $\mathbf{V}$ matrices) change when final demand (represented by the $\mathbf{Y}$ matrix) changes?" In the economic arena, Leontief's early work answered this question via a matrix inversion that now bears his name, the "Leontief inverse ($\mathbf{L}$)" [@Leontief:1941]. Analysts with an I-O background will know the famous equation $\mathbf{L} = (\mathbf{I} - \mathbf{A})^{-1}$. The `Recca` package provides functions that perform several "what if" analyses for the analyst. Each function has the name `new_*`, where `*` indicates the changed matrix or portion of the ECC. Some functions have the suffix `_ps` to indicate the functions assume perfect substitution (`ps`) of industry inputs throughout the ECC. The `new_*` functions return the resource ($\mathbf{R}$), use ($\mathbf{U}$), make ($\mathbf{V}$), and final demand ($\mathbf{Y}$) matrices that would be present under the conditions given by arguments to the `new_*` functions. Arguments for new or changed versions of vectors or matrices are given the suffix `_prime` in the `new_*` functions. For example, the changed version of the use matrix ($\mathbf{U}$) is called `U_prime`. For the examples that follow, we'll use one ECC from the `UKEnergy2000mats` data frame which represents a portion of the primary and final energy flows through the UK in the year 2000. ```r library(dplyr) library(magrittr) library(matsbyname) library(matsindf) library(Recca) library(tidyr) OurECC <- UKEnergy2000mats %>% dplyr::filter(Last.stage == "Final") %>% tidyr::spread(key = "matrix.name", value = "matrix") dplyr::glimpse(OurECC)
After a short discussion of the inputs to the new_*
functions, each
type of analysis is described in turn.
new_*
functionsInputs to the new_*
functions include matrices that describe the ECC
and matrices that describe the input-output structure of the ECC.
The new_*
functions take as inputs resource ($\mathbf{R}$), use
($\mathbf{U}$), make ($\mathbf{V}$), and final demand ($\mathbf{Y}$)
matrices that describe the ECC.
To look at the ECC, we can draw a Sankey diagram. A Sankey diagram for
the first row of the UKEnergyMatsWithR
data frame is given below.
make_sankey(OurECC) %>% magrittr::extract2("Sankey") %>% # Extracts the "Sankey" column magrittr::extract2(1) # Extracts the first row of the "Sankey" column
Each new_*
function requires basic knowledge about the I-O structure
of the ECCs in the form of named vectors and matrices. Thus, the first
step in any "what-if" analysis is to calculate the input-output
structure of the energy conversion chain. The calc_io_mats()
function
is the simplest way to obtain the necessary I-O structure, which appears
as additional columns appended at the right of the OurECC
data frame
in our example. (The names of the additional columns are given by
arguments to the calc_io_mats()
function.)
IO_mats <- OurECC %>% # Obtain the I-O structure of the ECCs calc_io_mats() # Note additional columns appended to the data frame. dplyr::glimpse(IO_mats)
With the I-O structure of the ECC determined (and represented by the
$\mathbf{q}$, $\mathbf{f}$, $\mathbf{h}$, $\mathbf{r}$ and $\mathbf{g}$ vectors and the
$\mathbf{W}$, $\mathbf{Z}$, $\mathbf{K}$, $\mathbf{C}$, $\mathbf{D}$, \mathbf{O},
$\mathbf{A}$, $\mathbf{L_{pxp}}$, and $\mathbf{L_{ixp}}$ matrices), we
can use the new_*
functions to ask "what if" questions.
The classic I-O question is "what if final demand ($\mathbf{Y}$)
changes?" Recca
has a function for that: new_Y()
. The new_Y()
function looks upstream in the ECC to determine the effects of a change
in final demand. To demonstrate, we'll double the Residential
final
demand for electricity from the grid (Elect - Grid
) in our ECC.
double <- function(x) { 2*x } DoubleRes <- IO_mats %>% mutate( Y_prime = matsbyname::elementapply_byname(double, a = Y, row = "Elect [from Grid]", col = "Residential") ) DoubleRes$Y[[1]] DoubleRes$Y_prime[[1]]
Now we can use the new_Y()
function to estimate the ECC with the
larger final demand for residential electricity. The original Sankey
diagram is:
make_sankey(OurECC) %>% extract2("Sankey") %>% # Extracts the "Sankey" column extract2(1) # Extracts the first row of the "Sankey" column
The new Sankey diagram is:
DoubleRes <- DoubleRes %>% new_Y() make_sankey(DoubleRes, R = "R_prime", U = "U_prime", V = "V_prime", Y = "Y_prime") %>% extract2("Sankey") %>% extract2(1)
Output from the electricity grid is clearly larger now than before. Also, upstream demand for natural gas is now larger than the upstream demand for crude, whereas in the original Sankey diagram, demand for crude was larger than the demand for natural gas.
new_Y()
estimates the upstream effects of a change to final demand. But
what if we want to understand the downstream effects of a change in
resource availability? The function new_R_ps()
supplies the answer.
new_R_ps()
takes as input the input-output structure of an ECC and the
efficiency of every intermediate industry. After discussing the resource
matrix and resource vectors, the new_R_ps()
function is demonstrated.
The rate of resource extraction is given by the $\mathbf{R}$ matrix or
by the $\mathbf{r}$ vector. The resource matrix ($\mathbf{R}$) is
Industry$\times$Product. Its industries are usually named
Resources - <Product>
, where <Product>
is the name of the Product
produced by that industry. (clean_byname()
removes 0
rows and
columns for clarity.)
OurECC$R[[1]] %>% clean_byname()
The resource vector ($\mathbf{r}$) is a Product column vector containing Products that are resources.
rvecs <- OurECC %>% transmute( r = clean_byname(R) %>% colsums_byname() %>% transpose_byname() ) rvecs$r[[1]]
The baseline $\mathbf{R}$ matrix is shown above. Let's say we want to
estimate the effect of a 50 % reduction in the production rate of crude
oil. So, we cut Resources - Crude
in half. To execute this reduction,
we'll use the matsbyname::elementapply_byname()
function.
half <- function(x){ x/2 } HalfCrude <- OurECC %>% # Obtain the I-O structure of the ECCs calc_io_mats(direction = "downstream") %>% mutate( R_prime = elementapply_byname(half, a = R, row = "Resources [of Crude]", col = "Crude") ) HalfCrude$R_prime[[1]] %>% clean_byname()
Now we use the new_R()
function to estimate changes in the ECC. But
first, we need to calculate the efficiency of all sectors in the ECC
using the calc_eta_i()
function.
HalfCrude <- HalfCrude %>% calc_eta_i() %>% new_R_ps() glimpse(HalfCrude)
After re-calculating the HalfCrude
ECC (specifically, after
calculating U_prime
, V_prime
, and Y_prime
), we can visualize the
effect of lower crude oil availability with a modified Sankey diagram.
First, we have the original Sankey diagram.
make_sankey(OurECC) %>% extract2("Sankey") %>% # Extracts the "Sankey" column extract2(1) # Extracts the first row of the "Sankey" column
And here is the modified Sankey diagram showing the much smaller
Resources - Crude
extraction rate.
make_sankey(HalfCrude, R = "R_prime", U = "U_prime", V = "V_prime", Y = "Y_prime") %>% extract2("Sankey") %>% # Extracts the "Sankey" column extract2(1) # Extracts the first row of the "Sankey" column
The Sankey diagrams clearly show that reducing the availability of crude
oil (Resources - crude
) means that less Transport
final demand can
be satisfied.
Note that both ECCs are in complete energy balance.
OurECC %>% verify_SUT_energy_balance_with_units() %>% select(Country, Year, Energy.type, Last.stage, .SUT_prod_energy_balance, .SUT_ind_energy_balance) %>% glimpse()
HalfCrude %>% mutate( R_plus_V_prime = sum_byname(R_prime, V_prime) ) %>% verify_SUT_energy_balance(R = "R_prime", U = "U_prime", V = "V_prime", Y = "Y_prime") %>% select(Country, Year, Energy.type, Last.stage, .SUT_energy_balance) %>% glimpse()
new_Y()
estimates the upstream effects of a change in final demand.
new_R_ps()
estimates the downstream effects of a change in resource
availability. But what if we want to estimate the effects of a change to
the inputs of an intermediate industry? If those inputs are perfectly
substitutable, the new_k_ps()
function provides an answer.
To demonstrate new_k_ps()
, we need an ECC that has at least two
reasonably-sized inputs. Unfortunately, OurECC
doesn't have the
necessary characteristics, so we create a new ECC here.
ECC below has two resource industries (R1 and R2), one intermediate industry (I), and two final demand sectors (Y1 and Y2). The R1 industry makes product R1p.\ The R2 industry makes product R2p. Industry I makes product Ip. Product Ip is consumed by final demand sectors Y1 and Y2.
The use ($\mathbf{U}$), make ($\mathbf{V}$), final demand ($\mathbf{Y}$), and unit summation ($\mathbf{S}_{units}$) matrices are given below.
U <- matrix(c(0, 0, 10, 0, 0, 10, 0, 0, 0), byrow = TRUE, nrow = 3, ncol = 3, dimnames = list(c("R1p", "R2p", "Ip"), c("R1", "R2", "I"))) %>% setrowtype("Products") %>% setcoltype("Industries") # There is no EIOU, so U_feed is the same as U U_feed <- U R_plus_V <- matrix(c(10, 0, 0, 0, 10, 0, 0, 0, 4), byrow = TRUE, nrow = 3, ncol = 3, dimnames = list(c("R1", "R2", "I"), c("R1p", "R2p", "Ip"))) %>% setrowtype("Industries") %>% setcoltype("Products") Y <- matrix(c(0, 0, 0, 0, 2, 2), byrow = TRUE, nrow = 3, ncol = 2, dimnames = list(c("R1p", "R2p", "Ip"), c("Y1", "Y2"))) %>% setrowtype("Products") %>% setcoltype("Industries") RV <- separate_RV(U = U, R_plus_V = R_plus_V) R <- RV$R V <- RV$V S_units <- matrix(c(1, 1, 1), byrow = TRUE, nrow = 3, ncol = 1, dimnames = list(c("R1p", "R2p", "Ip"), c("quad"))) %>% setrowtype("Products") %>% setcoltype("Units")
The Sankey diagram for this simple ECC is given below.
make_sankey(R = R, U = U, V = V, Y = Y) %>% extract2("Sankey")
We can change the proportion of inputs to industry I using new_k_ps()
.
To do so, we must first calculate the input-output structure of the ECC
using the calc_io_mats()
function. Then, we call the new_k_ps()
function with a new k vector that indicates industry I now uses 75/25
mixture of R1
and R2
instead of a 50/50 split between R1
and R2
.
simple_iomats <- calc_io_mats(R = R, U = U, U_feed = U_feed, V = V, Y = Y, S_units = S_units) k_prime <- matrix(c(0.75, 0.25), byrow = TRUE, nrow = 2, ncol = 1, dimnames = list(c("R1p", "R2p"), c("I"))) %>% setrowtype("Products") %>% setcoltype("Industries") change_input_proportions <- new_k_ps(c(simple_iomats, list(R = R, U = U, V = V, Y = Y, S_units = S_units, k_prime = k_prime))) make_sankey(R = change_input_proportions$R_prime, U = change_input_proportions$U_prime, V = change_input_proportions$V_prime, Y = Y) %>% extract2("Sankey")
In response to the different demands from industry I
, the rate of
resource extraction from R1
would need to grow, and the rate of
resource extraction from supply R2
would need to shrink. If there were
additional upstream industries, they would also change in response to
the new ratio of inputs to industry I
.
Recca
has three functions that allow an analyst to estimate the effect
of changes to an ECC.
new_Y()
estimates changes upstream of final demand.new_R_ps()
estimates changes downstream from resource extraction.new_k_ps()
estimates changes upstream of inputs to an intermediate
industry.The first of these functions (new_Y()
) was demonstrated in Heun et
al. [-@Heun:2018]. The
second and third functions (new_R_ps()
and new_k_ps()
) are shown
here for the first time.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.