Trends in US Electricity Generation and CO2 Emissions
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]")
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]")
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]")
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))
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
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.