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 filter(Category == "Power sector emissions") |> filter(State == 'US Total') |> filter(Variable == 'Total emissions') |> rename(emissions = Value) Generation Data Codedf_gen_yearly_UStot |> gt::gt() |> opt_row_striping() |> opt_interactive(use_highlight = TRUE, page_size_default = 5) Emissions Data Codedf_emis_yearly_UStot |> gt::gt() |> opt_row_striping() |> opt_interactive(use_highlight = TRUE, page_size_default = 5) 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). Codedf_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 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. Codedf_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 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. Codedf1 select(Year, emissions) df2 select(Year, generation) df_comb 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. Codedf_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. Codedf_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 Summary Total electricity generation has continued to increase (Figure 1) At the same time, total CO2 emissions from electricity generation have decreased (Figure 2) The amount of Emissions per generation (i.e. carbon intensity) has decreased over time (Figure 4), likely due in large part to a combination of a transition from coal to natural gas, and an increase in renewable energy. In a future analysis I will further break down the data by fuel type to get a better understanding of what is driving this trend. Further Exploration: Some of the areas I plan to explore in continuing analysis of this data include: Breaking down data by fuel types Looking at monthly data Examine correlation with weather/temperature Looking for changes in seasonal patterns of energy generation associated with home electrification (e.g. electric heat pumps replacing gas furnaces). Break down by individual states SessionInfo To make this analysis more reproducible, my SessionInfo is listed below. Codeutils::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 " />

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.

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.

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.

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)

Generation Data

Code
df_gen_yearly_UStot |>
  gt::gt() |> 
  opt_row_striping() |> 
  opt_interactive(use_highlight = TRUE, page_size_default = 5)

Emissions Data

Code
df_emis_yearly_UStot |> 
  gt::gt() |> 
  opt_row_striping() |> 
  opt_interactive(use_highlight = TRUE, page_size_default = 5)

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).

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

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.

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

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.

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.

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.

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

Summary

  • Total electricity generation has continued to increase (Figure 1)
  • At the same time, total CO2 emissions from electricity generation have decreased (Figure 2)
  • The amount of Emissions per generation (i.e. carbon intensity) has decreased over time (Figure 4), likely due in large part to a combination of a transition from coal to natural gas, and an increase in renewable energy. In a future analysis I will further break down the data by fuel type to get a better understanding of what is driving this trend.

Further Exploration:

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

  • Breaking down data by fuel types

  • Looking at monthly data

  • Examine correlation with weather/temperature

  • Looking for changes in seasonal patterns of energy generation associated with home electrification (e.g. electric heat pumps replacing gas furnaces).

  • Break down by individual states

SessionInfo

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

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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)