GDP & emissions - degrowthing or decoupling?
Friday fagpackets
One of a series…
What’s all this about de-growth?
<sigh>
A follow-up to @tom_rushby’s tweet
Updated after another by @JKSteinberger
Data
Downloaded from the awesome OurWorldInData:
absolute and per capita GDP
absolute and per capita Greenhouse Gas emissions in two flavours:
production (‘territorial’) and
consumption
Code
# fix
<- data.table::fread(here::here("data", "co2-emissions-and-gdp.csv"))
dt_abs <- data.table::fread(here::here("data", "co2-emissions-and-gdp-per-capita.csv")) dt_pc
Where do we care about?
Change these at will and for your purposes…
This would make a really nice shiny app
Code
<- c("United Kingdom", "United States", "New Zealand", "Australia",
entities_of_interest "China", "India", "Norway", "Kenya", "Jamaica")
# check valid
<- dt_pc[Entity %in% entities_of_interest, .(nObs = .N,
t meanAnnualPerCapTerr = mean(`Annual CO2 emissions (per capita)`, na.rm = TRUE),
meanAnnualPerCapCons = mean(`Annual consumption-based CO2 emissions (per capita)`,na.rm = TRUE),
meanAnnualGDPperCap = mean(`GDP per capita, PPP (constant 2017 international $)`,na.rm = TRUE)), keyby = .(Entity)]
::kable(t, digits = 2) %>%
knitrkable_styling()
Entity | nObs | meanAnnualPerCapTerr | meanAnnualPerCapCons | meanAnnualGDPperCap |
---|---|---|---|---|
Australia | 31 | 17.71 | 16.11 | 40887.80 |
China | 31 | 4.64 | 3.94 | 6980.80 |
India | 31 | 1.19 | 1.09 | 3639.23 |
Jamaica | 31 | 3.32 | 3.55 | 9564.31 |
Kenya | 31 | 0.28 | 0.39 | 3594.88 |
New Zealand | 31 | 8.09 | 8.69 | 35562.84 |
Norway | 31 | 8.93 | 9.85 | 57633.00 |
United Kingdom | 31 | 8.52 | 10.80 | 40041.50 |
United States | 31 | 19.09 | 20.00 | 51695.66 |
Absolute GDP & emissions
Absolute production emissions
First we’ll try production (‘territorial’) emissions. We are not controlling for population size so countries with large populations will visually dominate.
Code
<- dt_abs[Entity %in% entities_of_interest]
plotDT
::ggplot(plotDT, aes(x = as.numeric(`GDP, PPP (constant 2017 international $)`)/1000000000,
ggplot2y = as.numeric(`Annual CO2 emissions`)/1000000,
colour = Entity,
alpha = Year)) +
geom_point() +
labs(y = "Annual CO2 emissions (production-based, gT)",
x = "GDP $bn (constant 2017 $)",
caption = figCaption)
Absolute consumption emissions
Note that 2020 consumption-based emissions data is missing so you don’t see the 2020 COVID-19 downtick. Absolute emissions are falling in some places even as GDP is still increasing…
Code
<- dt_abs[Entity %in% entities_of_interest]
plotDT
::ggplot(plotDT, aes(x = as.numeric(`GDP, PPP (constant 2017 international $)`)/1000000000,
ggplot2y = as.numeric(`Annual consumption-based CO2 emissions`)/1000000,
colour = Entity,
alpha = Year)) +
geom_point() +
labs(y = "Annual CO2 emissions (consumption-based, gT)",
x = "GDP $bn (constant 2017 $)",
caption = figCaption)
Per capita GDP & emissions
Since we’ll be dividing everything pairwise by the same denominator, nothing much about the shapes should change… but the plots should be much clearer as we’ve removed the affect of population size. Countries with large populations will no longer visually dominate…
Production emissions
First we’ll try production emissions. Figure 3 shows change in this metric over time. Some interesting changes in direction (and otherwise)… basically they all need to be inverse U shaped, i.e. heading for y = 0.
Code
<- c(entities_of_interest, "World")
entities_of_interest
<- dt_pc[Entity %in% entities_of_interest]
plotDT
<-ggplot2::ggplot(plotDT, aes(x = as.numeric(`GDP per capita, PPP (constant 2017 international $)`),
p y = as.numeric(`Annual CO2 emissions (per capita)`),
colour = Entity,
alpha = Year)) +
geom_point() +
geom_line() +
labs(y = "Annual CO2 emissions per capita (production-based, T)",
x = "GDP per capita (constant 2017 $)",
caption = figCaption)
p
Let’s repeat that. Hover over the dots to see which is which. This is plotly in action #YMMV.
Code
<-ggplot2::ggplot(plotDT, aes(x = as.numeric(`GDP per capita, PPP (constant 2017 international $)`),
p y = as.numeric(`Annual CO2 emissions (per capita)`),
colour = Entity)) +
geom_point() +
geom_line() +
labs(y = "Annual CO2 emissions per capita (production-based, T)",
x = "GDP per capita (constant 2017 $)",
caption = figCaption)
::ggplotly(p) plotly
Now let’s have a look at all the countries but without the lines.
Quite interesting, Qatar for example. Perfect place for a winter sport’s World Cup. Trinidad and Tobago also worth a look. Macao looks like the place to be?
Code
#plotDT <- dt_pc[Entity %in% entities_of_interest]
<- dt_pc # for fun
plotDT
<- ggplot2::ggplot(plotDT, aes(x = as.numeric(`GDP per capita, PPP (constant 2017 international $)`),
p y = as.numeric(`Annual CO2 emissions (per capita)`),
colour = Entity,
alpha = Year)) +
geom_point() +
theme(legend.position = "none") +
labs(y = "Annual CO2 emissions per capita (production-based, T)",
x = "GDP per capita (constant 2017 $)",
caption = figCaption)
::ggplotly(p) plotly
Consumption emissions
Next we’ll try consumption emissions. This is shown in Figure 6.
Note that 2020 consumption-based emissions data is missing so you don’t see the down-tick.
Code
<- dt_pc[Entity %in% entities_of_interest]
plotDT
::ggplot(plotDT, aes(x = as.numeric(`GDP per capita, PPP (constant 2017 international $)`),
ggplot2y = as.numeric(`Annual consumption-based CO2 emissions (per capita)`),
colour = Entity,
alpha = Year)) +
geom_point() +
geom_line() +
labs(y = "Annual CO2 emissions per capita (consumption-based, T)",
x = "GDP per capita (constant 2017 $)",
caption = figCaption)
Let’s repeat that for all countries. Hover over the dots to see which is which #YMMV.
Well this time Luxembourg is out in the lead…
Code
#plotDT <- dt_pc[Entity %in% entities_of_interest]
<- dt_pc # for fun
plotDT
<- ggplot2::ggplot(plotDT, aes(x = as.numeric(`GDP per capita, PPP (constant 2017 international $)`),
p y = as.numeric(`Annual consumption-based CO2 emissions (per capita)`),
colour = Entity,
alpha = Year)) +
geom_point() +
theme(legend.position = "none") +
labs(y = "Annual CO2 emissions per capita (consumption-based, T)",
x = "GDP per capita (constant 2017 $)",
caption = figCaption)
::ggplotly(p) plotly
Efficiency
How about looking at efficiency: gC02e per $ GDP?
Following https://timjackson.org.uk/earth-vs-growth/ …
Code
`Emissions intensity (production-based)` := `Annual CO2 emissions`/`GDP, PPP (constant 2017 international $)`*1000*1000] dt_abs[,
Code
<- dt_abs[Entity %in% entities_of_interest]
plotDT
::ggplot(plotDT, aes(Year, `Emissions intensity (production-based)`, colour = Entity)) +
ggplot2geom_line() +
labs(y = "gC02 per $ GDP",
colour = "Country",
caption = figCaption)
For the UK, let’s say c. 300g/$ in 1995 reducing to 200g/$ in 2010. So 15 years. To go from 200g/$ to zero at the same rate would take approx. 30 years. So net-zero by 2050?
Regardless of whether that aligns with science-based targets (i.e. absolute zero by 2044) … what happens if the economy grows … by say 2-3% per year? … would that force total emissions up (fixed intensity) or result in efficiency gains (lower intensity)?
Code
`Emissions intensity (consumption-based)` := `Annual consumption-based CO2 emissions`/`GDP, PPP (constant 2017 international $)`*1000*1000] dt_abs[,
Code
<- dt_abs[Entity %in% entities_of_interest]
plotDT
::ggplot(plotDT, aes(Year, `Emissions intensity (consumption-based)`, colour = Entity)) +
ggplot2geom_line() +
labs(y = "gC02 per $ GDP",
caption = figCaption)
Warning: Removed 22 rows containing missing values (`geom_line()`).
Whom do we love?
Data descriptions
Check
Skim the absolute data:
Code
::skim(dt_abs) skimr
Warning: Couldn't find skimmers for class: integer64; No user-defined `sfl`
provided. Falling back to `character`.
Warning: Couldn't find skimmers for class: integer64; No user-defined `sfl`
provided. Falling back to `character`.
Name | dt_abs |
Number of rows | 7795 |
Number of columns | 8 |
Key | NULL |
_______________________ | |
Column type frequency: | |
character | 4 |
numeric | 4 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
Entity | 0 | 1.00 | 4 | 32 | 0 | 255 | 0 |
Code | 0 | 1.00 | 0 | 8 | 931 | 225 | 0 |
Annual CO2 emissions | 479 | 0.94 | 1 | 21 | 0 | 6137 | 0 |
GDP, PPP (constant 2017 international $) | 1626 | 0.79 | 1 | 21 | 0 | 6162 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Year | 0 | 1.00 | 2005.06 | 8.930000e+00 | 1990.00 | 1997.00 | 2005.00 | 2013.00 | 2.02000e+03 | ▇▇▇▇▇ |
Annual consumption-based CO2 emissions | 3730 | 0.52 | 976326173.39 | 3.366486e+09 | 197201.67 | 10759532.52 | 59975058.69 | 290854945.27 | 3.67025e+10 | ▇▁▁▁▁ |
Emissions intensity (production-based) | 2105 | 0.73 | 263.56 | 2.409400e+02 | 9.15 | 122.67 | 196.73 | 309.26 | 2.30112e+03 | ▇▁▁▁▁ |
Emissions intensity (consumption-based) | 4295 | 0.45 | 291.92 | 1.686800e+02 | 4.19 | 179.06 | 251.82 | 365.36 | 1.82195e+03 | ▇▂▁▁▁ |
Skim the per capita data
Code
::skim(dt_pc) skimr
Name | dt_pc |
Number of rows | 7745 |
Number of columns | 6 |
Key | NULL |
_______________________ | |
Column type frequency: | |
character | 2 |
numeric | 4 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
Entity | 0 | 1 | 4 | 32 | 0 | 252 | 0 |
Code | 0 | 1 | 0 | 8 | 899 | 224 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Year | 0 | 1.00 | 2005.07 | 8.93 | 1990.00 | 1997.00 | 2005.00 | 2013.00 | 2020.00 | ▇▇▇▇▇ |
GDP per capita, PPP (constant 2017 international $) | 1579 | 0.80 | 17879.29 | 20132.68 | 436.72 | 3678.83 | 10365.78 | 25832.03 | 161971.47 | ▇▂▁▁▁ |
Annual consumption-based CO2 emissions (per capita) | 3680 | 0.52 | 6.53 | 6.92 | 0.05 | 1.19 | 4.30 | 9.89 | 57.79 | ▇▂▁▁▁ |
Annual CO2 emissions (per capita) | 492 | 0.94 | 5.11 | 6.44 | 0.02 | 0.77 | 2.97 | 7.42 | 68.72 | ▇▁▁▁▁ |
Code
# hidden chunk