library(pacman); p_load(DT, ggplot2, ggrepel, sandwich, lmtest, ggthemr, gganimate, tidyverse, transformr, gifski, png, cowplot)
CRITR <- function(n, alpha = .05) {
df <- n - 2; CRITT <- qt(alpha/2, df, lower.tail = F)
CRITR <- sqrt((CRITT^2)/((CRITT^2) + df ))
return(CRITR)}
datatable(data, extensions = c("Buttons", "FixedColumns"), options = list(dom = 'Bfrtip', buttons = c('copy', 'csv', 'print'), scrollX = T, fixedColumns = list(leftColumns = 3)))
datatable(longdata, extensions = c("Buttons", "FixedColumns"), options = list(dom = 'Bfrtip', buttons = c('copy', 'csv', 'print'), scrollX = T, fixedColumns = list(leftColumns = 3)))
CRITR(25, c(.05, .10)); CRITR(24, c(.05, .10))
## [1] 0.3960697 0.3365235
## [1] 0.4043863 0.3437826
Data was derived from Eurostat (https://ec.europa.eu/eurostat/databrowser/explore/all/all_themes) and all data was for the year 2021 and countries with complete data. The EU as a whole was included, but it can be removed. This can be updated when full-year 2022 data is available. Energy is from NRG_BAL_C, Complete energy balances, Total, Wind, Solar thermal, and Solar photovoltaic. Prices are in Euros per kilowatt-hour and come from NRG_PC_204, Electricity prices for household consumers - bi-annual data (from 2007 onwards). Population is from DEMO_PJAN, Population on 1 January by age and sex. Gas prices are in Euros per kilowatt-hour and come from NRG_PC_202, Gas prices for household consumers - bi-annual data (from 2007 onwards). Energy prices are inclusive of taxes and levies unless “NTL” is appended to their variable label. Data was downloaded on January 19th, 2023.
Since a precedent has been established that larger shares of intermittent generation lead to high system LCOE (Ueckerdt et al., 2013; Devanney, 2020, Figure A.4) and accordingly higher energy prices in general, the one-sided p-value of .05, i.e., two-sided .10 is justifiable.
This page provides charts for an update on Devanney’s observation that electricity costs are elevated where intermittent generation is more substantial because those places are forced to support the costs of two generation systems: “the intermittent, and the dispatchable.” (p. 221). Specifically, he dealt with per capita intermittent renewables generation. Per capita intermittent renewables may be more interesting than proportional or total because they have to do with the amount of these generation sources people use and the corresponding compensation required by the dispatchable generation system when they aren’t working. Low-energy use/high intermittent proportion countries may get by fairly well price-wise. In order, I will produce three plots:
Additionally, I will present the same plots for
The motivation behind this is related to the premise above and phenomena like the Duck curve. Simply put, just as dispatchables become more expensive with lots of renewable generation and especially so with substantial overgeneration, so should their fuels. I assume this will occur due to their increased demand by individual firms as the number of firms declines, signaling more limited buying power on a country-wise basis. This should only work if there are frictions involved in gas transport. Because this was not previously attested to in sources I have mentioned or, indeed, sources I know of, I will use a two-sided p-value. Additionally, two-sided p-values will be used for the second plot as its estimand was neither noted by Devanney nor Ueckerdt et al. Robust regressions will be utilized to assess the impact of outliers and otherwise high-leverage datapoints.
Excludes “EU” since it depends on the other datapoints, in addition to excluded ones.
cor(data$ProportionIntermittent[2:25], data$X2021AvgPrice[2:25]) #Significant
## [1] 0.5400473
cor(data$SumIntermittent[2:25], data$X2021AvgPrice[2:25]) #Significant
## [1] 0.562577
cor(data$RenewablesPerCapita[2:25], data$X2021AvgPrice[2:25]) #Significant
## [1] 0.7404015
cor(data$ProportionIntermittent[2:25], data$X2021AvgPriceGas[2:25]) #Not significant
## [1] 0.3793902
cor(data$SumIntermittent[2:25], data$X2021AvgPriceGas[2:25]) #Not significant
## [1] 0.3072885
cor(data$RenewablesPerCapita[2:25], data$X2021AvgPriceGas[2:25]) #Significant
## [1] 0.8055705
cor(log(data$ProportionIntermittent[2:25]), log(data$X2021AvgPrice[2:25])) #Significant
## [1] 0.538532
cor(log(data$SumIntermittent[2:25]), log(data$X2021AvgPrice[2:25])) #Significant
## [1] 0.5030351
cor(log(data$RenewablesPerCapita[2:25]), log(data$X2021AvgPrice[2:25])) #Significant
## [1] 0.5966373
cor(log(data$ProportionIntermittent[2:25]), log(data$X2021AvgPriceGas[2:25])) #Significant
## [1] 0.5437281
cor(log(data$SumIntermittent[2:25]), log(data$X2021AvgPriceGas[2:25])) #Significant
## [1] 0.607839
cor(log(data$RenewablesPerCapita[2:25]), log(data$X2021AvgPriceGas[2:25])) #Significant
## [1] 0.7457957
Note that some of the logged results have reduced sample sizes.
Mod1 <- lm(scale(X2021AvgPrice) ~ scale(ProportionIntermittent), data[2:25,])
Mod2 <- lm(scale(X2021AvgPrice) ~ scale(SumIntermittent), data[2:25,])
Mod3 <- lm(scale(X2021AvgPrice) ~ scale(RenewablesPerCapita), data[2:25,])
Mod4 <- lm(scale(X2021AvgPriceGas) ~ scale(ProportionIntermittent), data[2:25,])
Mod5 <- lm(scale(X2021AvgPriceGas) ~ scale(SumIntermittent), data[2:25,])
Mod6 <- lm(scale(X2021AvgPriceGas) ~ scale(RenewablesPerCapita), data[2:25,])
LMod1 <- lm(log(scale(X2021AvgPrice)) ~ log(scale(ProportionIntermittent)), data[2:25,])
LMod2 <- lm(log(scale(X2021AvgPrice)) ~ log(scale(SumIntermittent)), data[2:25,])
LMod3 <- lm(log(scale(X2021AvgPrice)) ~ log(scale(RenewablesPerCapita)), data[2:25,])
LMod4 <- lm(log(scale(X2021AvgPriceGas)) ~ log(scale(ProportionIntermittent)), data[2:25,])
LMod5 <- lm(log(scale(X2021AvgPriceGas)) ~ log(scale(SumIntermittent)), data[2:25,])
LMod6 <- lm(log(scale(X2021AvgPriceGas)) ~ log(scale(RenewablesPerCapita)), data[2:25,])
VC1 <- vcovHC(Mod1, type = "HC5")
VC2 <- vcovHC(Mod2, type = "HC5")
VC3 <- vcovHC(Mod3, type = "HC5")
VC4 <- vcovHC(Mod4, type = "HC5")
VC5 <- vcovHC(Mod5, type = "HC5")
VC6 <- vcovHC(Mod6, type = "HC5")
VC7 <- vcovHC(LMod1, type = "HC5")
VC8 <- vcovHC(LMod2, type = "HC5")
VC9 <- vcovHC(LMod3, type = "HC5")
VC10 <- vcovHC(LMod4, type = "HC5")
VC11 <- vcovHC(LMod5, type = "HC5")
VC12 <- vcovHC(LMod6, type = "HC5")
RM1 <- coeftest(Mod1, vcov = VC1); round(RM1, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.180 0.000 1.000
## scale(ProportionIntermittent) 0.540 0.238 2.268 0.033 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM2 <- coeftest(Mod2, vcov = VC2); round(RM2, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.167 0.000 1
## scale(SumIntermittent) 0.563 0.073 7.677 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM3 <- coeftest(Mod3, vcov = VC3); round(RM3, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.138 0.00 1
## scale(RenewablesPerCapita) 0.740 0.133 5.58 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM4 <- coeftest(Mod4, vcov = VC4); round(RM4, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.189 0.000 1.000
## scale(ProportionIntermittent) 0.379 0.139 2.729 0.012 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM5 <- coeftest(Mod5, vcov = VC5); round(RM5, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.252 0.000 1.000
## scale(SumIntermittent) 0.307 0.655 0.469 0.644
RM6 <- coeftest(Mod6, vcov = VC6); round(RM6, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.000 0.126 0.000 1
## scale(RenewablesPerCapita) 0.806 0.177 4.554 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM7 <- coeftest(LMod1, vcov = VC7); round(RM7, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.411 0.443 -0.928 0.396
## log(scale(ProportionIntermittent)) 0.374 0.422 0.884 0.417
RM8 <- coeftest(LMod2, vcov = VC8); round(RM8, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.696 0.684 -1.018 0.384
## log(scale(SumIntermittent)) 0.333 0.592 0.563 0.613
RM9 <- coeftest(LMod3, vcov = VC9); round(RM9, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.006 0.217 -0.028 0.979
## log(scale(RenewablesPerCapita)) 0.418 0.197 2.119 0.078 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM10 <- coeftest(LMod4, vcov = VC10); round(RM10, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.987 0.397 -2.484 0.056 .
## log(scale(ProportionIntermittent)) -0.150 0.403 -0.373 0.724
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM11 <- coeftest(LMod5, vcov = VC11); round(RM11, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.896 0.451 -1.987 0.118
## log(scale(SumIntermittent)) -0.784 0.287 -2.730 0.052 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RM12 <- coeftest(LMod6, vcov = VC12); round(RM12, 3)
##
## t test of coefficients:
##
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.747 0.370 -2.020 0.083 .
## log(scale(RenewablesPerCapita)) 1.250 0.281 4.451 0.003 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
ggthemr("dust")
ggplot(data[2:25,], aes(x = ProportionIntermittent, y = X2021AvgPrice)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Proportion Intermittent Generation") +
ylab("2021 Electricity Price") +
ggtitle("Electricity Cost vs. Proportion Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country))
ggplot(data[2:25,], aes(x = SumIntermittent, y = X2021AvgPrice)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Total Intermittent Generation") +
ylab("2021 Electricity Price") +
ggtitle("Electricity Cost vs. Total Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country))
ggplot(data[2:25,], aes(x = log(SumIntermittent), y = log(X2021AvgPrice))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Log Total Intermittent Generation") +
ylab("Log 2021 Electricity Price") +
ggtitle("Log Electricity Cost vs. Log Total Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country)) +
scale_x_continuous(breaks = c(4, 6,8), labels = c(round(exp(4), 3), round(exp(6), 3), round(exp(8), 3))) +
scale_y_continuous(breaks = c(-2, -1.5), labels = c(round(exp(-2), 3), round(exp(-1.5), 3)))
ggplot(data[2:25,], aes(x = RenewablesPerCapita, y = X2021AvgPrice)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Per Capita Intermittent Generation") +
ylab("2021 Electricity Price") +
ggtitle("Electricity Cost vs. Per Capita Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country)) +
scale_x_continuous(labels = scales::label_comma())
ggplot(data[2:25,], aes(x = ProportionIntermittent, y = X2021AvgPriceGas)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Proportion Intermittent Generation") +
ylab("2021 Gas Price") + #Not vehicle gasoline
ggtitle("Gas Cost vs. Proportion Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country))
ggplot(data[2:25,], aes(x = SumIntermittent, y = X2021AvgPriceGas)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Total Intermittent Generation") +
ylab("2021 Gas Price") +
ggtitle("Gas Cost vs. Total Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country))
ggplot(data[2:25,], aes(x = log(SumIntermittent), y = log(X2021AvgPriceGas))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Log Total Intermittent Generation") +
ylab("Log 2021 Gas Price") +
ggtitle("Log Gas Cost vs. Log Total Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country)) +
scale_x_continuous(breaks = c(4, 6,8), labels = c(round(exp(4), 3), round(exp(6), 3), round(exp(8), 3))) +
scale_y_continuous(breaks = c(-3.5, -3.0, -2.5, -2.0), labels = c(round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2), 3)))
ggplot(data[2:25,], aes(x = RenewablesPerCapita, y = X2021AvgPriceGas)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040") +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
xlab("Per Capita Intermittent Generation") +
ylab("2021 Gas Price") +
ggtitle("Gas Cost vs. Per Capita Intermittent Generation (Solar, Wind)") +
geom_text_repel(aes(label = Country)) +
scale_x_continuous(labels = scales::label_comma())
longdata <- longdata[longdata$Country != "EU27", ]
I purged the EU27 entries for this because it depended on other entries.
ggthemr("solarized")
p <- longdata %>%
filter(!is.na(IntermittentPerCapita | ElecPriceAvg)) %>%
ggplot(aes(x = IntermittentPerCapita, y = ElecPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Electricity Price vs. Per Capita Intermittent Generation in Europe in Year: {frame_time}", x = "Per Capita Intermittent Generation", y = "Electricity Price") +
transition_time(Year) +
ease_aes("linear") +
#view_follow() + # If you want the axes to move
shadow_wake(wake_length = .1, alpha = F, exclude_layer = 2) +
scale_x_continuous(labels = scales::label_comma())
animate(p, fps = 30, nframes = 800, height = 1440, width = 2560, res = 300)
ggthemr("solarized")
p <- longdata %>%
filter(!is.na(IntermittentPerCapita | GasPriceAvg)) %>%
ggplot(aes(x = IntermittentPerCapita, y = GasPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Gas Price vs. Per Capita Intermittent Generation in Europe in Year: {frame_time}", x = "Per Capita Intermittent Generation", y = "Gas Price") +
transition_time(Year) +
ease_aes("linear") +
shadow_wake(wake_length = .1, alpha = F, exclude_layer = 2) +
scale_x_continuous(labels = scales::label_comma())
animate(p, fps = 30, nframes = 800, height = 1440, width = 2560, res = 300)
The proportion graphs are logged to make results more visible and to fix issues with limited variance in proportion units. To avoid issues with logging a single axis, both are logged, which seems appropriate since they are both all-positive.
ggthemr("solarized")
p <- longdata %>%
filter(!is.na(IntermittentProportion | ElecPriceAvg)) %>%
ggplot(aes(x = log(IntermittentProportion), y = log(ElecPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Electricity Price vs. Log Proportion Intermittent Generation
in Europe in Year: {frame_time}", x = "Log Proportion Intermittent Generation", y = "Log Electricity Price") +
transition_time(Year) +
ease_aes("linear") +
shadow_wake(wake_length = .1, alpha = F, exclude_layer = 2) +
scale_x_continuous(breaks = c(-10, -5, 0), labels = c(round(exp(-10), 3), round(exp(-5), 3), round(exp(0), 3))) +
scale_y_continuous(breaks = c(-3.5, -3.0, -2.5, -2.0, -1.5), labels = c(round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3), round(exp(-1.5), 3)))
animate(p, fps = 30, nframes = 800, height = 1440, width = 2560, res = 300)
ggthemr("solarized")
p <- longdata %>%
filter(!is.na(IntermittentProportion | GasPriceAvg)) %>%
ggplot(aes(log(IntermittentProportion), y = log(GasPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Gas Price vs. Log Proportion Intermittent Generation in Europe in Year: {frame_time}", x = "Log Proportion Intermittent Generation", y = "Log Gas Price") +
transition_time(Year) +
ease_aes("linear") +
shadow_wake(wake_length = .1, alpha = F, exclude_layer = 2) +
scale_x_continuous(breaks = c(-10, -5, 0), labels = c(round(exp(-10), 3), round(exp(-5), 3), round(exp(0), 3))) +
scale_y_continuous(breaks = c(-4.0, -3.5, -3.0, -2.5, -2.0), labels = c(round(exp(-4.0), 3), round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3)))
animate(p, fps = 30, nframes = 800, height = 1440, width = 2560, res = 300)
FacetGraph <- longdata %>%
filter(!is.na(IntermittentPerCapita | ElecPriceAvg)) %>%
ggplot(aes(x = IntermittentPerCapita, y = ElecPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Electricity Price vs. Per Capita Intermittent Generation in Europe by Year", x = "Per Capita Intermittent Generation", y = "Electricity Price") +
facet_wrap("Year") +
scale_x_continuous(labels = scales::label_comma())
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentPerCapita | GasPriceAvg)) %>%
ggplot(aes(x = IntermittentPerCapita, y = GasPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Gas Price vs. Per Capita Intermittent Generation in Europe by Year", x = "Per Capita Intermittent Generation", y = "Gas Price") +
facet_wrap("Year") +
scale_x_continuous(labels = scales::label_comma())
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentPerCapita | ElecPriceAvg)) %>%
ggplot(aes(x = log(IntermittentPerCapita), y = log(ElecPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Electricity Price vs. Log Per Capita Intermittent Generation in Europe by Year", x = "Log Per Capita Intermittent Generation", y = "Log Electricity Price") +
facet_wrap("Year") +
scale_x_continuous(breaks = c(-20, -16, -12, -8), labels = c(round(exp(-20), 9), round(exp(-16), 8), round(exp(-12), 5), round(exp(-8), 4))) +
scale_y_continuous(breaks = c(-3.5, -3.0, -2.5, -2.0, -1.5), labels = c(round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3), round(exp(-1.5), 3)))
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentPerCapita | GasPriceAvg)) %>%
ggplot(aes(x = log(IntermittentPerCapita), y = log(GasPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Gas Price vs. Log Per Capita Intermittent Generation in Europe by Year", x = "Log Per Capita Intermittent Generation", y = "Log Gas Price") +
facet_wrap("Year") +
scale_x_continuous(breaks = c(-20, -16, -12, -8), labels = c(round(exp(-20), 9), round(exp(-16), 8), round(exp(-12), 5), round(exp(-8), 4))) +
scale_y_continuous(breaks = c(-4.0, -3.5, -3.0, -2.5, -2.0), labels = c(round(exp(-4.0), 3), round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3)))
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentProportion | ElecPriceAvg)) %>%
ggplot(aes(x = IntermittentProportion, y = ElecPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Electricity Price vs. Proportion Intermittent Generation in Europe by Year", x = "Proportion Intermittent Generation", y = "Electricity Price") +
facet_wrap("Year") +
scale_x_continuous(labels = scales::label_comma())
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentProportion | GasPriceAvg)) %>%
ggplot(aes(x = IntermittentProportion, y = GasPriceAvg)) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Gas Price vs. Proportion Intermittent Generation in Europe by Year", x = "Proportion Intermittent Generation", y = "Gas Price") +
facet_wrap("Year") +
scale_x_continuous(labels = scales::label_comma())
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentProportion | ElecPriceAvg)) %>%
ggplot(aes(x = log(IntermittentProportion), y = log(ElecPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Electricity Price vs. Log Proportion Intermittent Generation in Europe by Year", x = "Log Proportion Intermittent Generation", y = "Log Electricity Price") +
facet_wrap("Year") +
scale_x_continuous(breaks = c(-10, -5, 0), labels = c(round(exp(-10), 3), round(exp(-5), 3), round(exp(0), 3))) +
scale_y_continuous(breaks = c(-3.5, -3.0, -2.5, -2.0, -1.5), labels = c(round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3), round(exp(-1.5), 3)))
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
FacetGraph <- longdata %>%
filter(!is.na(IntermittentProportion | GasPriceAvg)) %>%
ggplot(aes(x = log(IntermittentProportion), y = log(GasPriceAvg))) +
geom_point() +
geom_smooth(method = "lm", formula = "y ~ x", color = "#e69040", se = T) +
theme(legend.position = "none", text = element_text(size = 12),
plot.title = element_text(hjust = .5)) +
labs(title = "Log Gas Price vs. Log Proportion Intermittent Generation in Europe by Year", x = "Log Proportion Intermittent Generation", y = "Log Gas Price") +
facet_wrap("Year") +
scale_x_continuous(breaks = c(-10, -5, 0), labels = c(round(exp(-10), 3), round(exp(-5), 3), round(exp(0), 3))) +
scale_y_continuous(breaks = c(-4.0, -3.5, -3.0, -2.5, -2.0), labels = c(round(exp(-4.0), 3), round(exp(-3.5), 3), round(exp(-3.0), 3), round(exp(-2.5), 3), round(exp(-2.0), 3)))
ggdraw(FacetGraph) + draw_label(x = .885, y = .15, "Relationship by
Year")
As Devanney found, per-capita intermittent generation is related to prices. In the latest complete-year data, it appears to also be strongly related to gas prices, but there is not a consistent order, perhaps because of other differences in energy mix, such as Sweden’s reliance on biofuels or because a large total generation capacity like Germany’s has still implies a lot of demand. As Ueckerdt et al. found, the proportion of renewables is related to cost. The existence of a high system LCOE for intermittent generation was still true in Europe in 2021.
The findings motivated by Devanney and Ueckerdt et al. were not explicable by taxes and levies, as when they were removed, the results remained significant and directionally consistent. The correlations changed to, in order, .591, .333, .554, .454, .271, and .699, and the p-values from the robust regressions became .025, .260, .024, <2e-16, .690, and .017. Bonferroni-corrected, these were no longer significant, and taking into account the correlations among the tests, these became .059, .611, .056, still <.001, 1.62, and .040, meaning the four significant results were winnowed down to just two, both of which were for gas costs. There is, thus, an argument to be made that these results were ultimately not significant purely because I decided to add two tests using total intermittent generation as an independent variable. If these tests - which were not motivated by the literature - were removed, the results without taxes and levies remain significant across the board, if only marginally. Clearly, the results for total intermittent generation capacity may have been more heavily impacted by taxes and levies, and across the board, robust regressions were more mutable by correction for multiple comparisons. Without it, results like the first and fourth correlations without taxes and levies could remain significant even in the face of naive - but not correlation-adjusted - Bonferroni correction.
Nonlinearity may be relevant here, but there is not enough power to assess it. HC5 robust standard errors turned the nonsignificant relationship between the proportion of intermittent generation and gas prices significant, indicating a role for outliers, heteroskedasticity, high leverage datapoints, etc.
I have plotted multiple years of data, and because other years covered different countries, there are more of them in the temporal dataset, too. The positive relationship between intermittent renewables shares and electric costs replicates across every year of available data. It may be obscured during the ongoing energy crisis, but, if so, it will probably become less obscured when the crisis abates. On the other hand, the proportion of intermittent renewables was only occasionally related to electric and gas prices. Having a cheap source of baseload like hydro, geothermal, or nuclear would help a lot with cost containment at a high proportion of intermittent renewables.
A recent paper (Matsuo, 2022) also covered the topic of system LCOE.
After posting this, I was informed that what I wrote above about the proportion of intermittents versus costs was often incorrect because the arithmetic scale I used was incapable of showing the relationship with prices and I should have used a log scale due to scaling issues it fixes. Results involving the proportion of intermittents immediately became highly significant and consistent with the intermittents per capita results after doing this. Though I have been convinced I was wrong about the null results for the proportions above, I will cite Rothman, Wise & Hatch (2011) as a justification for the continued used of arithmetic scales, but in doing so, I do not wish to say that I don’t appreciate that a log scale was more appropriate for this data and inferences without it were incorrect.
Ueckerdt, F., Hirth, L., Luderer, G., & Edenhofer, O. (2013). System LCOE: What are the costs of variable renewables? Energy, 63, 61–75. https://doi.org/10.1016/j.energy.2013.10.072
Devanney, J. (2020). Why Nuclear Power Has Been a Flop: At Solving the Gordian Knot of Electricity Poverty and Global Warming. BookBaby.
Matsuo, Y. (2022). Re-Defining System LCOE: Costs and Values of Power Sources. Energies, 15(18), Article 18. https://doi.org/10.3390/en15186845
Rothman, K. J., Wise, L. A., & Hatch, E. E. (2011). Should Graphs of Risk or Rate Ratios be Plotted on a Log Scale? American Journal of Epidemiology, 174(3), 376–377. https://doi.org/10.1093/aje/kwr156
sessionInfo()
## R version 4.2.1 (2022-06-23 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19044)
##
## Matrix products: default
##
## locale:
## [1] LC_COLLATE=English_United States.utf8
## [2] LC_CTYPE=English_United States.utf8
## [3] LC_MONETARY=English_United States.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United States.utf8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] cowplot_1.1.1 png_0.1-7 gifski_1.6.6-1 transformr_0.1.4
## [5] forcats_0.5.2 stringr_1.4.1 dplyr_1.0.10 purrr_0.3.5
## [9] readr_2.1.3 tidyr_1.2.1 tibble_3.1.8 tidyverse_1.3.2
## [13] gganimate_1.0.8 ggthemr_1.1.0 lmtest_0.9-40 zoo_1.8-11
## [17] sandwich_3.0-2 ggrepel_0.9.2 ggplot2_3.4.0 DT_0.26
## [21] pacman_0.5.1
##
## loaded via a namespace (and not attached):
## [1] nlme_3.1-157 fs_1.5.2 sf_1.0-9
## [4] lubridate_1.8.0 progress_1.2.2 httr_1.4.4
## [7] tools_4.2.1 backports_1.4.1 bslib_0.4.0
## [10] utf8_1.2.2 R6_2.5.1 KernSmooth_2.23-20
## [13] mgcv_1.8-40 DBI_1.1.3 colorspace_2.0-3
## [16] withr_2.5.0 tidyselect_1.2.0 prettyunits_1.1.1
## [19] compiler_4.2.1 cli_3.4.1 rvest_1.0.3
## [22] xml2_1.3.3 labeling_0.4.2 sass_0.4.2
## [25] scales_1.2.1 classInt_0.4-8 proxy_0.4-27
## [28] digest_0.6.29 rmarkdown_2.17 pkgconfig_2.0.3
## [31] htmltools_0.5.3 highr_0.9 dbplyr_2.3.0
## [34] fastmap_1.1.0 htmlwidgets_1.5.4 rlang_1.0.6
## [37] readxl_1.4.1 rstudioapi_0.14 jquerylib_0.1.4
## [40] farver_2.1.1 generics_0.1.3 jsonlite_1.8.2
## [43] crosstalk_1.2.0 googlesheets4_1.0.1 magrittr_2.0.3
## [46] Matrix_1.5-1 Rcpp_1.0.9 munsell_0.5.0
## [49] fansi_1.0.3 lifecycle_1.0.3 stringi_1.7.8
## [52] yaml_2.3.5 grid_4.2.1 crayon_1.5.2
## [55] lattice_0.20-45 splines_4.2.1 haven_2.5.1
## [58] hms_1.1.2 knitr_1.40 pillar_1.8.1
## [61] lpSolve_5.6.17 reprex_2.0.2 glue_1.6.2
## [64] evaluate_0.17 modelr_0.1.10 vctrs_0.5.2
## [67] tzdb_0.3.0 tweenr_2.0.2 cellranger_1.1.0
## [70] gtable_0.3.1 assertthat_0.2.1 cachem_1.0.6
## [73] xfun_0.33 broom_1.0.1 e1071_1.7-11
## [76] class_7.3-20 googledrive_2.0.0 gargle_1.2.1
## [79] units_0.8-1 ellipsis_0.3.2