Causal inference to scope environmental impact assessment of renewable energy projects and test competing mental models of decarbonization
Amir M Gazar, Mark E Borsuk, Ryan SD Calder
Environmental impact assessment (EIA), life cycle analysis (LCA), and cost benefit analysis (CBA) embed crucial but subjective judgments over the extent of system boundaries and the range of impacts to consider as causally connected to an intervention, decision, or technology of interest. EIA is increasingly the site of legal, political, and social challenges to renewable energy projects proposed by utilities, developers, and governments, which, cumulatively, are slowing decarbonization. Environmental advocates in the United States have claimed that new electrical interties with Canada increase development of Canadian hydroelectric resources, leading to environmental and health impacts associated with new reservoirs. Assertions of such second-order impacts of two recently proposed 9.5 TWh year-1 transborder transmission projects played a role in their cancellation. We recast these debates as conflicting mental models of decarbonization, in which values, beliefs, and interests lead different parties to hypothesize causal connections between interrelated processes (in this case, generation, transmission, and associated impacts). We demonstrate via Bayesian network modeling that development of Canadian hydroelectric resources is stimulated by price signals and domestic demand rather than increased export capacity per se. However, hydropower exports are increasingly arranged via long-term power purchase agreements that may promote new generation in a way that is not easily modeled with publicly available data. We demonstrate the utility of causal inference for structured analysis of sociotechnical systems featuring complex mechanisms that are not easily modeled mechanistically. In the setting of decarbonization, such analysis can fill a gap in available energy systems models that focus on long-term optimum portfolios and do not generally represent questions of incremental causality of interest to stakeholders at the local level. More broadly, these tools can increase the evidentiary support required for consequentialist (as opposed to attributional) LCA and CBA, for example, in calculating indirect emissions of renewable energy projects.
Keywords: Renewable energy, Causal inference, Cost benefit analysis, Life cycle assessment, Sociotechnical systems, Energy policy
- Overview
- Repo Contents
- System Requirements
- Installation Guide
- Developed New Functions
- Citation.bib
- Copyrights
This repository contains data, instructions, and code for the "Do electrical interties stimulate Canadian hydroelectric development? Using causal inference to scope environmental impact assessment in evolving sociotechnical systems" paper. This repository includes R code, a manual for using the code and utilizing the bnlearn
[1] package in this context, and a real dataset for practical application.
-
R files: contains
R
files - doc: code reproduction information, manual for using the
bnlearn
package on our dataset - data: real dataset to use in the
R
session - citation: bib code to use when citing this code or the manuscript
- license: creative commons attribution 4.0 international license
- misc: includes miscellaneous files such as source code to generate Figure 4 in the manuscript
We utilized a MacBook Pro with an Apple M1 Pro chip, featuring an 8-core CPU and 16 GB of memory. The startup disk is the Macintosh HD. The system operates on macOS 13.2.1 (22D68) Ventura
.
This code is tested on macOS operating systems. The Comprehensive R Archive Network (CRAN) package which is the underlying softawre for this code, is compatible with Windows, Mac, and Linux operating systems.
Before setting up the R
code, users should have R
version 4.3.1 (2023-06-16) Beagle Scouts or higher, and several packages set up from CRAN.
You can download and install R
via CRAN
for free from this link.
You can download and install R Studio
for free from this link.
Users should install the following packages prior to running the supplied R
code, from an R
terminal:
install.packages(c("bnlearn", "gRain", "visNetwork", "ggplot2",
"zoo", "scales", "gridExtra", "dplyr", "MASS", "svglite", "tidyverse"))
which will install in about a few minutes on a machine with similar specs.
All packages in their latest versions as they appear on CRAN
on November 10, 2013. The versions of packages are:
Rgraphviz 2.44.0
bnlearn 4.8.3
gRain 1.3.13
visNetwork 2.1.2
ggplot2 3.4.2
zoo 1.8.12
scales 1.2.1
gridExtra 2.3
dplyr 1.1.2
MASS 7.3.60
svglite 2.1.1
tidyverse 2.0.0
The runtime on our operating system for this code in R
is approximately 15 seconds.
We have developed the following functions to simplify the algorithm:
We have created the dsep.dag
function that can evaluate d-separation for any given node pair. This function uses the optimized DAG results to identify the following for each node pair and then calculates conditional independence: 1. Parents; 2. Neighbors (i.e., parents and children for each node); and 3. Markov-Blanket (i.e., parents, children, and parents of children for each node). Furthermore, this function uses data to evaluate d-separation in addition to the results of DAG discovery. This combines the functionalities of the ci.test
and dsep
functions available in the bnlearn
package. Where ci.test
exclusively utilizes data, while dsep.dag
solely employs DAGs.
dsep.dag(x, data, z)
The dsep.dag
function accepts the following parameters:
x
: an object of classbn
data
: a data frame containing the variables in the modelz
: a list, where each element is a character vector representing a pair of node labels
The plot.network
function visualizes and returns DAGs returned by the bnlearn
package.
plot.network(structure, ht = "400px", title)
The plot.network
function accepts the following parameters:
structure
: an object of classbn
ht
: a string specifying the height of the plot. If none is specified, the default value will be 400pxtitle
: a character string, the title of the plot. If none is specified, the title will be blank
The transform_and_test
function evaluates the data set, checks for normality (using the Shapiro-Wilk test), and transforms the non-Gaussian variables using the Box-Cox transformation. Re-evaluates the transformed variables with the Shapiro-Wilk test and checks for normality. Returns the results.
transform_and_test(data, z)
The transform_and_test
function accepts the following parameters:
data
: a data frame containing the variables in the modelz
: a list, where each element is a character vector representing a variable
The evaluate_fit_continuous
and evaluate_fit_discrete
functions evaluate each variable's goodness of fit for the DAGs produced by the bnlearn
package. The evaluate_fit_continuous
evaluate continious variables and the evaluate_fit_discrete
evaluates discrete variables.
evaluate_fit_continuous(data, pred)
The evaluate_fit_continuous
function accepts the following parameters:
data
: a data frame containing continuous variables in the modelpred
: a data frame containing continuous variables' predictions using the model
evaluate_fit_discrete(data, pred)
The evaluate_fit_discrete
function accepts the following parameters:
data
: a data frame containing discrete variables in the modelpred
: a data frame containing discrete variables' predictions using the model
This work is licensed under a Creative Commons Attribution 4.0 International License.