Site icon R-bloggers

Trends in US Electricity Generation and CO2 Emissions

[This article was first published on Andy Pickering, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
< section id="introduction" class="level1">

Introduction

In this analysis I look at trends in US electricity generation and associated CO2 emissions, using a nice data set available from Ember. Ember provides monthly and yearly data on US electricity generation and emissions for the total US as well as by state, both in total and broken down by fuel types. In this first look at the data, I will limit my analysis to yearly data and total US generation/emissions.

< section id="data" class="level1">

Data

Data was downloaded from https://ember-climate.org/data-catalogue/us-electricity-data/ as a csv file and read into R. Some unnecessary columns were dropped, and the data is subsetted into separate data frames for total US generation and emissions.

< details>< summary>Code
suppressPackageStartupMessages(library(tidyverse))
library(gt)
theme_set(theme_gray(base_size = 16))

# read yearly data
# Data only contains USA, so we can drop country column and some other un-needed ones

df_yearly <- readr::read_csv('data/us_yearly_full_release_long_format-2.csv', 
                      show_col_types = FALSE) |> 
  select(-c(Country,`Country code`,`State code`,
            `YoY % change`,`YoY absolute change`))


# make separate dataframe for just Electricity generation data
# This contains both actual generation (gWh) and % of total gen for each fuel type

df_gen_yearly_UStot <- df_yearly |> 
  filter(Category == "Electricity generation") |> 
  filter(Variable == "Total Generation") |> 
  filter(State == 'US Total') |> 
  select(-c("State","State type")) |> 
  rename(generation = Value)



# make separate dataframe for just Power sector emissions data (not generation)
df_emis_yearly_UStot <- df_yearly |> 
  filter(Category == "Power sector emissions") |> 
  filter(State == 'US Total') |> 
  filter(Variable == 'Total emissions') |> 
  rename(emissions = Value)
< section id="generation-data" class="level2">

Generation Data

< details open="">< summary>Code
df_gen_yearly_UStot |>
  gt::gt() |> 
  opt_row_striping() |> 
  opt_interactive(use_highlight = TRUE, page_size_default = 5)
< section id="emissions-data" class="level2">

Emissions Data

< details open="">< summary>Code
df_emis_yearly_UStot |> 
  gt::gt() |> 
  opt_row_striping() |> 
  opt_interactive(use_highlight = TRUE, page_size_default = 5)
< section id="electricity-generation" class="level1">

Electricity Generation

First I’ll look at the time series of US electricity generation (Figure 1). We can see that generation has generally increased over time, though it appears to have been relatively flat from about 2008-2017. There was a significant decrease in 2009 (possibly related to the 2008 recession), and also in 2020 (possibly related to the Covid-19 pandemic).

< details open="">< summary>Code
df_gen_yearly_UStot |> 
  ggplot(aes(Year, generation)) +
  geom_point(size = 4) +
  ggtitle("Total US Yearly Electricity Generation") +
  ylab("[GWh]")

Figure 1: Timeseries of yearly US electricity generation
< section id="emissions" class="level1">

Emissions

Next I’ll look at the time series of emissions from the power sector. Figure 2 shows that US power sector emissions were increasing up to about 2007, but have been steadily decreasing over time since then.

< details open="">< summary>Code
df_emis_yearly_UStot |> 
  ggplot(aes(Year, emissions)) +
  geom_point(size = 4) +
  geom_smooth(formula = y ~ x, method = "loess") +
  ggtitle("Total CO2 Emissions From Electricity Generation") +
  ylab("Emissions [ktCO2]")

Figure 2: Timeseries of yearly US emissions from electricity generation
< section id="emissions-vs-generation" class="level1">

Emissions vs Generation

So far we have sen that electricity generation has been generally increasing over time, while the associated CO2 emissions have been decreasing.

< details open="">< summary>Code
df1 <- df_emis_yearly_UStot |> 
  select(Year, emissions)

df2 <- df_gen_yearly_UStot |> 
  select(Year, generation) 

df_comb <- df1 |> 
  inner_join(df2,by = join_by(Year)) |> 
  mutate(emis_per_gen = emissions/generation)

Figure 3 shows a scatter plot of total US yearly emissions vs electricity generation, with the color corresponding to the year. This shows a trend of decreasing emissions over time, even as generation has increased.

< details open="">< summary>Code
df_comb |> 
  ggplot(aes(generation, emissions)) +
  geom_point(size = 5, aes(color = Year)) +
  xlab("Generation [GWh]") +
  ylab("Emissions [ktCO2]")

Figure 3: Scatterplot of total US yearly emissions vs electricity generation

An easier way to visualize this trend is to plot the emissions/generation (i.e the CO2 intensity) over time, shown in Figure 4. In this figure, the size of the points are also proportional to the value of generation.

< details open="">< summary>Code
df_comb |> 
  ggplot(aes(Year, emis_per_gen)) +
  geom_point(aes(size = generation), color = 'lightblue', alpha = 1) +
  ylab("ktCO2 / GWh") +
  ggtitle("Yearly US Emissions/Generation") +
  scale_size(range = c(0,9))

Figure 4: Timeseries of total US yearly Emssions/Generation, sized by value of generation
< section id="summary" class="level1">

Summary

< section id="further-exploration" class="level2">

Further Exploration:

Some of the areas I plan to explore in continuing analysis of this data include:

< section id="sessioninfo" class="level1">

SessionInfo

To make this analysis more reproducible, my SessionInfo is listed below.

< details open="">< summary>Code
utils::sessionInfo()
R version 4.3.1 (2023-06-16)
Platform: x86_64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.1.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/Denver
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] gt_0.10.0       lubridate_1.9.3 forcats_1.0.0   stringr_1.5.0  
 [5] dplyr_1.1.3     purrr_1.0.2     readr_2.1.4     tidyr_1.3.0    
 [9] tibble_3.2.1    ggplot2_3.4.4   tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] sass_0.4.7        utf8_1.2.4        generics_0.1.3    renv_1.0.3       
 [5] xml2_1.3.5        lattice_0.22-5    stringi_1.7.12    hms_1.1.3        
 [9] digest_0.6.33     magrittr_2.0.3    evaluate_0.22     grid_4.3.1       
[13] timechange_0.2.0  fastmap_1.1.1     Matrix_1.6-1.1    jsonlite_1.8.7   
[17] mgcv_1.9-0        fansi_1.0.5       crosstalk_1.2.0   scales_1.2.1     
[21] cli_3.6.1         rlang_1.1.1       crayon_1.5.2      splines_4.3.1    
[25] ellipsis_0.3.2    bit64_4.0.5       munsell_0.5.0     reactR_0.5.0     
[29] withr_2.5.1       yaml_2.3.7        tools_4.3.1       parallel_4.3.1   
[33] tzdb_0.4.0        colorspace_2.1-0  vctrs_0.6.4       R6_2.5.1         
[37] lifecycle_1.0.3   reactable_0.4.4   htmlwidgets_1.6.2 bit_4.0.5        
[41] vroom_1.6.4       pkgconfig_2.0.3   pillar_1.9.0      gtable_0.3.4     
[45] glue_1.6.2        xfun_0.40         tidyselect_1.2.0  rstudioapi_0.15.0
[49] knitr_1.44        farver_2.1.1      nlme_3.1-163      htmltools_0.5.6.1
[53] labeling_0.4.3    rmarkdown_2.25    compiler_4.3.1   
< !-- -->
To leave a comment for the author, please follow the link and comment on their blog: Andy Pickering.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Exit mobile version