1 About

Code copyright (c) 2024 the author

License:

To cite:

Code:

3 Data

This analysis uses the New Zealand Electricity Authority’s Generation data.

Values are in kWh per half hour https://www.emi.ea.govt.nz/Wholesale/Datasets/Generation/Generation_MD

As far as we can work out this data does not include distributed (i.e. non-grid connected) generation such as small scale wind, solar, hydro, biomass etc which is connected to the LV network. This means the EA data is likely to underestimate total generation and potentially underestimate the proportion of total generation that is renewable. It is possible that this could be fixed using embedded wind & solar generation data from the metered embedded generation data although this may still not include household level (micro)generation.

rmdParams$olderThan <- 7

If the data we have previously downloaded is more than 7` days old, re-download.

rmdParams$dataPath <- "~/Dropbox/data/NZ_ElecAuth/processed/"

# load all the files we have using rbindlist
# probably ought to do some filtering here
filesToLoad <- list.files(rmdParams$dataPath, pattern = ".csv", 
                          full.names = TRUE)

orig_DT <- rbindlist(lapply(filesToLoad, fread))
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
## Warning in rbindlist(lapply(filesToLoad, fread)): Coercing 'character' RHS
## to 'integer' to match the type of column 7 named 'Trading_Date'.
## Warning in rbindlist(lapply(filesToLoad, fread)): NAs introduced by
## coercion
setnames(orig_DT, "rDateTime", "dv_dateTime")

message("Original data range from: ", min(orig_DT$dv_dateTime, na.rm = TRUE))
## Original data range from: 2010-01-01 00:15:00
message("...to: ", max(orig_DT$dv_dateTime , na.rm = TRUE))
## ...to: 2024-10-31 23:45:00
# make wide for ease of aggregation ----
# sum over fuel code
orig_DT[, kWh := as.numeric(kWh)] # just in case
## Warning in eval(jsub, SDenv, parent.frame()): NAs introduced by coercion
nzGenMix_wide_dt <- dcast(orig_DT[!is.na(dv_dateTime)], dv_dateTime ~ Fuel_Code, value.var = "kWh", fun.aggregate = sum)
## Processed 400728 groups out of 1686616. 24% done. Time elapsed: 3s. ETA: 9s.Processed 542244 groups out of 1686616. 32% done. Time elapsed: 4s. ETA: 8s.Processed 679066 groups out of 1686616. 40% done. Time elapsed: 5s. ETA: 7s.Processed 796407 groups out of 1686616. 47% done. Time elapsed: 6s. ETA: 6s.Processed 936044 groups out of 1686616. 55% done. Time elapsed: 7s. ETA: 5s.Processed 1074430 groups out of 1686616. 64% done. Time elapsed: 8s. ETA: 4s.Processed 1212355 groups out of 1686616. 72% done. Time elapsed: 9s. ETA: 3s.Processed 1350327 groups out of 1686616. 80% done. Time elapsed: 10s. ETA: 2s.Processed 1492444 groups out of 1686616. 88% done. Time elapsed: 11s. ETA: 1s.Processed 1630927 groups out of 1686616. 97% done. Time elapsed: 12s. ETA: 0s.Processed 1686616 groups out of 1686616. 100% done. Time elapsed: 12s. ETA: 0s.
# add derived variables used later ----
addDerivedVars <- function(dt){
  dt[, dv_year := lubridate::year(dv_dateTime)]
dt[, dv_date := lubridate::as_date(dv_dateTime)]
dt[, dv_month := lubridate::month(dv_dateTime)]
dt[, dv_hour := lubridate::hour(dv_dateTime)]
dt[, dv_hms := hms::as_hms(dv_dateTime)]
dt <- gridCarbon::add_season(dt, 
                                 dateVar = "dv_dateTime",
                                 h = "S")
dt <- gridCarbon::add_peakPeriod(dt, 
                                      dateTime = "dv_dateTime")
  return(dt)
}

nzGenMix_wide_dt <- addDerivedVars(nzGenMix_wide_dt)
nzGenMix_dt <- addDerivedVars(orig_DT[!is.na(dv_dateTime)])

#message("Remove incomplete years to avoid weird things in plots.")

message("Filtered data range from: ", min(nzGenMix_wide_dt$dv_dateTime))
## Filtered data range from: 2010-01-01 00:15:00
message("...to: ", max(nzGenMix_wide_dt$dv_dateTime))
## ...to: 2024-10-31 23:45:00
rmdParams$plotCap <- paste0("Data: NZ EA Generation ",
                   min(nzGenMix_wide_dt$dv_date), " - ",
                   max(nzGenMix_wide_dt$dv_date),
                            "\nPlot: @dataknut \nCode: https://github.com/dataknut/gridCarbon")

# > recent date cut ----
recentDateCut <- max(nzGenMix_wide_dt$dv_date - (6*30)) # roughly 6 months

Note:

  • the data may cover more years than we need
  • the data may contain partial years - BEWARE incomplete years in plots using annual totals or means across all months.

4 Recreating DrSimEvans’ plot

Inspired by https://twitter.com/DrSimEvans/status/1508409309775994892

Which explored the relationship between % renewable and fossil-fuel generation for Great Britain (see also https://dataknut.github.io/gridCarbon/gbGenMixTrends.html)

This looks like daily data.

  • Solar + wind (% of gen) vs coal + gas (and % of gen))
# add together the % and totals we want (half-hourly)

nzGenMix_wide_dt[, dv_total := Coal + Diesel + Gas + Geo + Hydro + Solar + Wind + Wood]
nzGenMix_wide_dt[, dv_coal_gas := Coal + Gas]
nzGenMix_wide_dt[, dv_coal_gas_pc := 100 * dv_coal_gas/dv_total]
nzGenMix_wide_dt[, dv_solar_wind := Solar + Wind]
nzGenMix_wide_dt[, dv_solar_wind_pc := 100 * dv_solar_wind/dv_total]

# keep the vars we want for clarity
temp <- nzGenMix_wide_dt[, .(dv_dateTime, dv_coal_gas, dv_solar_wind,
                    dv_coal_gas_pc, dv_solar_wind_pc, dv_total)]

temp[, dv_date := lubridate::date(dv_dateTime)]

# aggregate to daily data for plotting
plotDT <- temp[,
               .(mean_dv_solar_wind_pc = mean(dv_solar_wind_pc),
                 mean_dv_coal_gas_pc = mean(dv_coal_gas_pc),
                 total_dv_coal_gas = sum(dv_coal_gas),
                 total_dv_solar_wind = sum(dv_solar_wind),
                 total_dv_total = sum(dv_total),
                 nObs = .N), # to check for days with < 48 half hours
               keyby = .(dv_date)
               ]
plotDT[, dv_year := lubridate::year(dv_date)] # for plots
plotDT[, total_dv_coal_gas_pc := 100 * total_dv_coal_gas/total_dv_total] # daily %
plotDT[, total_dv_solar_wind_pc := 100 * total_dv_solar_wind/total_dv_total]

message("Check for days with less than 48 hours - this will be truncated data due to DST breaks. We hate DST breaks")
## Check for days with less than 48 hours - this will be truncated data due to DST breaks. We hate DST breaks
table(plotDT$nObs)
## 
##   46   48 
##   15 5403

Figure 4.1 shows the mean half-hourly % generation by each type per day. This is slightly convoluted - it is the mean of the sum of the 48 daily half-hourly values. Unfold the code above for clarity.

The smoothed curves are estimated for each year. The lines terminate at the maximum value for the year. I’m still trying to decide if they tell us anything useful.

ggplot2::ggplot(plotDT[dv_year > 2011], aes(x = mean_dv_solar_wind_pc, 
                            y = mean_dv_coal_gas_pc,
                            colour = as.factor(dv_year),
                            alpha = dv_year)) +
  geom_point() +
  geom_smooth() +
  scale_colour_viridis_d(name = "Year") +
  guides(alpha = "none") +
  labs(x = "Solar & wind (mean % of half-hourly generation per day)",
       y = "Coal & gas (mean % of half-hourly generation per day)",
       caption = rmdParams$plotCap)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Mean half-hourly % generation by each type per day

Figure 4.1: Mean half-hourly % generation by each type per day

# save it
ggplot2::ggsave(filename = "meanNZrenewablesVsfossilHalfHourPC.png", 
                path = rmdParams$plotPath,
                height = 5)
## Saving 7 x 5 in image
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Figure 4.2 shows the percentage of daily generation by type. This is less convoluted as it is the sum of generation per day for the two categories (solar + wind vs gas + coal) as a % of total daily generation.

Again the smoothed curve is estimated for each year.

ggplot2::ggplot(plotDT[dv_year > 2011], aes(x = total_dv_solar_wind_pc, 
                            y = total_dv_coal_gas_pc,
                            colour = as.factor(dv_year),
                            alpha = dv_year)) +
  geom_point() +
  geom_smooth() +
  scale_colour_viridis_d(name = "Year") +
  guides(alpha = "none") +
  labs(x = "Solar & wind (% of total daily generation)",
       y = "Coal & gas (% of total daily generation)",
       caption = rmdParams$plotCap)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Percentage of daily generation by type

Figure 4.2: Percentage of daily generation by type

ggplot2::ggsave(filename = "dailyNZpcGenMix.png", 
                path = rmdParams$plotPath,
                height = 5)
## Saving 7 x 5 in image
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

4.1 Half-hourly versions of the plot

Just cos we can… helpfully split into ‘peak’ and ‘off peak’ periods.

Peak period definitions:

  • Morning 07:00 - 09:00
  • Daytime 09:00 - 16:00
  • Evening 16:00 - 21:00
  • Night - all other times

Again the smoothed curve is estimated for each year (and demand period).

ggplot2::ggplot(nzGenMix_wide_dt[dv_year > 2011], aes(x = dv_solar_wind_pc, 
                            y = dv_coal_gas_pc,
                            alpha = dv_year,
                            colour = as.factor(dv_year))) +
  geom_point() +
  facet_wrap(. ~ dv_peakPeriod) +
  geom_smooth() +
  scale_colour_viridis_d(name = "Year") +
  guides(alpha = "none") +
  labs(x = "Solar & wind (% of half-hourly generation)",
       y = "Coal & gas (% of half-hourly generation)",
       caption = rmdParams$plotCap)
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
## Warning: Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Caused by error in `gam.reparam()`:
## ! NA/NaN/Inf in foreign function call (arg 3)
Percentage of half-hourly generation by type

Figure 4.3: Percentage of half-hourly generation by type

ggplot2::ggsave(filename = "halfHourlyNZ_PCgenByPeakPeriod.png", 
                path = rmdParams$plotPath,
                height = 5)
## Saving 7 x 5 in image
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'
## Warning: Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Failed to fit group 4.
## Caused by error in `gam.reparam()`:
## ! NA/NaN/Inf in foreign function call (arg 3)

7 Fuel types and time of day ‘demand’

Do we see a relationship between generation fuels and peak demand? This will be mediated by the way the electricity market works.

We may find wind curtailment (not visible here) at low demand periods where geothermal can’t be shut off.

First, what is the general average shape of overall generation?

‘Peak periods’ shown as shaded rectangles

# orginal values are kWh
plotDT <- nzGenMix_wide_dt[, .(mean_total_GWh = mean(dv_total/1000000),
                               mean_renewables_GWh = mean(RENEWABLE/1000000),
                               mean_renewables_pc = mean(RENEWABLE_perc),
                               mean_hydro_GWh = mean(Hydro/1000000),
                               mean_hydro_pc = mean(HYDRO_perc),
                               mean_coal_GWh = mean(Coal/1000000),
                               mean_coal_pc = mean(COAL_perc),
                               mean_gas_GWh = mean(Gas/1000000),
                               mean_gas_pc = mean(GAS_perc)), keyby = .(dv_hms, dv_year, dv_season, dv_peakPeriod)]

make_profilePlot <- function(dt, yVar = "mean_renewables_GWh", yVarLab = "change me"){
  plotDT <- dt[, .(x = dv_hms, y = get(yVar), alpha = dv_year, 
                   group = dv_year,
                   facet1 = dv_season,
                   colour = dv_peakPeriod)]
  p <- ggplot2::ggplot(plotDT, aes(x = x, 
                                   y = y,
                            alpha = alpha,
                            group = group)) +
    geom_rect(aes(xmin=hms::as_hms("07:00:00"), xmax=hms::as_hms("09:00:00"),
                  ymin=min(plotDT$y), ymax=max(plotDT$y)),
                              fill='pink', alpha=0.1) +
        geom_rect(aes(xmin=hms::as_hms("16:00:00"), xmax=hms::as_hms("21:00:00"),
                  ymin=min(plotDT$y), ymax=max(plotDT$y)),
                              fill='pink', alpha=0.1) +
  geom_line() +
  scale_alpha_continuous(name = "Year") +
  facet_wrap(facet1 ~ .) +
    labs(x = "Time of day",
       y = yVarLab,
       caption = rmdParams$plotCap) +
  theme(axis.text.x = element_text(angle = 45, hjust=1)) +
    scale_x_time(breaks = scales::breaks_width("120 min")) 
  return(p)
}

make_profilePlot(plotDT, "mean_total_GWh", "Mean total (GWh)")
Mean half-hourly generation by year and season

Figure 7.1: Mean half-hourly generation by year and season

Contribution of renewables…

make_profilePlot(plotDT, "mean_renewables_GWh", "Mean renewables (GWh)")
Mean half-hourly % renewable generation by year and season

Figure 7.2: Mean half-hourly % renewable generation by year and season

make_profilePlot(plotDT, "mean_renewables_pc", "Mean % renewables")
Mean half-hourly % renewable generation by year and season

Figure 7.3: Mean half-hourly % renewable generation by year and season

What is hydro’s contribution?

make_profilePlot(plotDT, "mean_hydro_GWh", "Mean hydro (GWh)")
Mean half-hourly % hydro generation by year and season

Figure 7.4: Mean half-hourly % hydro generation by year and season

make_profilePlot(plotDT, "mean_hydro_pc", "Mean % hydro")
Mean half-hourly % hydro generation by year and season

Figure 7.5: Mean half-hourly % hydro generation by year and season

What is coal’s contribution?

make_profilePlot(plotDT, "mean_coal_GWh", "Mean coal (GWh)")
Mean half-hourly % coal generation by year and season

Figure 7.6: Mean half-hourly % coal generation by year and season

make_profilePlot(plotDT, "mean_coal_pc", "Mean % coal")
Mean half-hourly % coal generation by year and season

Figure 7.7: Mean half-hourly % coal generation by year and season

What is gas’s contribution?

make_profilePlot(plotDT, "mean_gas_GWh", "Mean gas (GWh")
Mean half-hourly % gas generation by year and season

Figure 7.8: Mean half-hourly % gas generation by year and season

make_profilePlot(plotDT, "mean_gas_pc", "Mean % gas")
Mean half-hourly % gas generation by year and season

Figure 7.9: Mean half-hourly % gas generation by year and season

Relationship between hydro and overall generation

ggplot2::ggplot(nzGenMix_wide_dt, aes(y = Hydro/1000000, x = dv_total/1000000, colour = dv_peakPeriod)) +
  geom_point() +
  facet_grid(dv_year ~ dv_season) +
  labs(y = "Hydro GWh per half hour",
       x = "Total GWh per half hour")

YMMV on 7.10

plotDT <- nzGenMix_wide_dt[, .(mean_renewables_GWh = mean(RENEWABLE/1000000),
                 mean_generation_GWh = mean(dv_total/1000000)),
             keyby = .(dv_year, dv_hms, dv_peakPeriod, dv_season)]

ggplot2::ggplot(plotDT, aes(x = mean_generation_GWh , y = mean_renewables_GWh,
                                         colour = dv_peakPeriod)) +
  geom_point() +
  scale_color_discrete(name = "Period") +
  facet_grid(dv_season ~ dv_year) +
  labs(x = "Mean half-hourly generation (GWh)",
       y = "Mean half-hourly renewables (GWh)",
       caption = rmdParams$plotCap)
Mean renewables vs Mean total generation

Figure 7.10: Mean renewables vs Mean total generation

8 Summary

That’s it.

You might want to look at recent academic research on this topic:

  • (Staffell 2017)
  • (Staffell and Pfenninger 2018)

9 Annex

9.2 Data descriptors

9.2.1 NZ generation ‘fuel sources’

t <- nzGenMix_dt[, .(TWh = sum(kWh/1000000000)), keyby =.(Fuel_Code, Tech_Code)]

dct <- dcast(t, Fuel_Code ~ Tech_Code)
## Using 'TWh' as value column. Use 'value.var' to override
knitr::kable(dct, digits = 3, caption = "Fuel codes by technology code (total TWh in dataset)")
Table 9.1: Fuel codes by technology code (total TWh in dataset)
Fuel_Code Cogen Geo Hydro Solar Thrml Wind
Coal NA NA NA NA 23.097 NA
Diesel NA NA NA NA 0.066 NA
Gas 13.445 NA NA NA 64.437 NA
Gas&Oil NA NA NA NA 0.000 NA
Geo NA 89.439 NA NA NA NA
Hydro NA NA 321.466 NA NA NA
Solar NA NA NA 0.042 NA NA
Wind NA NA NA NA NA 28.258
Wood 3.181 NA NA NA NA NA

9.2.2 NZ annual generation % by fuel code

Table 9.2 shows annual GWh and % GWh by fuel code.

t <- nzGenMix_dt[, .(GWh = sum(kWh/1000000), na.rm = TRUE),
                 keyby = .(dv_year, Fuel_Code)]
t[, GWh_pc := 100*GWh/sum(GWh), keyby = .(dv_year)]

dct <- dcast(t, dv_year ~ Fuel_Code, value.var = "GWh")
knitr::kable(dct, digits = 2,
             caption = "GWh per year by Fuel Code - beware incomplete years")
Table 9.2: GWh per year by Fuel Code - beware incomplete years
dv_year Coal Diesel Gas Gas&Oil Geo Hydro Solar Wind Wood
2010 2603.07 1.48 7935.46 0 5380.56 23996.73 NA 1593.11 249.76
2011 1846.13 0.46 7490.50 0 5645.07 24350.71 NA 1823.75 235.69
2012 2883.91 2.54 8202.50 0 5740.41 22104.06 NA 1895.02 268.21
2013 2013.99 2.48 7833.49 NA 5919.11 22385.31 NA 1865.04 275.90
2014 1280.19 0.79 5732.63 NA 5503.81 20313.43 NA 1576.89 222.25
2015 0.00 NA NA NA NA 4757.45 NA 53.09 NA
2016 160.34 0.77 1950.47 NA 2956.09 13472.10 NA 830.84 90.97
2017 904.01 3.19 6321.03 NA 7348.49 24224.16 NA 1678.37 257.80
2018 1172.10 6.44 5152.13 NA 7186.04 25301.65 NA 1658.30 220.02
2019 1611.55 2.68 5464.55 NA 7208.82 24654.80 NA 1829.08 249.63
2020 1733.88 4.43 5544.49 NA 7552.72 23402.44 NA 2138.96 240.85
2021 2540.83 17.95 4789.51 NA 7561.92 23338.75 NA 2482.90 242.53
2022 955.02 3.35 4231.26 NA 7424.67 25136.27 NA 2694.68 220.00
2023 1563.78 0.88 3238.85 NA 7142.26 25369.50 NA 3073.45 204.99
2024 1828.50 18.99 3995.20 NA 6868.86 18658.93 41.91 3064.58 202.73
dct <- dcast(t, dv_year ~ Fuel_Code, value.var = "GWh_pc")
knitr::kable(dct, digits = 1,
             caption = "% GWh per year by Fuel Code - beware incomplete years")
Table 9.2: % GWh per year by Fuel Code - beware incomplete years
dv_year Coal Diesel Gas Gas&Oil Geo Hydro Solar Wind Wood
2010 6.2 0.0 19.0 0 12.9 57.5 NA 3.8 0.6
2011 4.5 0.0 18.1 0 13.6 58.8 NA 4.4 0.6
2012 7.0 0.0 20.0 0 14.0 53.8 NA 4.6 0.7
2013 5.0 0.0 19.4 NA 14.7 55.6 NA 4.6 0.7
2014 3.7 0.0 16.6 NA 15.9 58.7 NA 4.6 0.6
2015 0.0 NA NA NA NA 98.9 NA 1.1 NA
2016 0.8 0.0 10.0 NA 15.2 69.2 NA 4.3 0.5
2017 2.2 0.0 15.5 NA 18.0 59.5 NA 4.1 0.6
2018 2.9 0.0 12.7 NA 17.7 62.2 NA 4.1 0.5
2019 3.9 0.0 13.3 NA 17.6 60.1 NA 4.5 0.6
2020 4.3 0.0 13.7 NA 18.6 57.6 NA 5.3 0.6
2021 6.2 0.0 11.7 NA 18.5 57.0 NA 6.1 0.6
2022 2.3 0.0 10.4 NA 18.3 61.8 NA 6.6 0.5
2023 3.9 0.0 8.0 NA 17.6 62.5 NA 7.6 0.5
2024 5.3 0.1 11.5 NA 19.8 53.8 0.1 8.8 0.6

9.2.3 NZ gen mix data

skimr::skim(nzGenMix_wide_dt)
Table 9.3: Data summary
Name nzGenMix_wide_dt
Number of rows 260034
Number of columns 35
Key dv_dateTime
_______________________
Column type frequency:
Date 1
difftime 2
factor 2
numeric 29
POSIXct 1
________________________
Group variables None

Variable type: Date

skim_variable n_missing complete_rate min max median n_unique
dv_date 0 1 2010-01-01 2024-10-31 2017-06-01 5418

Variable type: difftime

skim_variable n_missing complete_rate min max median n_unique
dv_hms 0 1 900 secs 85500 secs 42300 secs 48
hms 0 1 900 secs 85500 secs 42300 secs 48

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
dv_season 0 1 FALSE 4 Aut: 66240, Win: 66240, Spr: 64050, Sum: 63504
dv_peakPeriod 0 1 FALSE 5 Ear: 75852, Day: 75852, Eve: 43344, Lat: 43314

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Coal 0 1 88824.21 93755.15 0.00 0.00 70009.00 146550.25 484036.00 ▇▃▂▁▁
Diesel 0 1 255.45 3023.48 0.00 0.00 0.00 0.00 79835.00 ▇▁▁▁▁
Gas 0 1 299507.31 180203.34 0.00 183142.00 300442.30 419389.03 868672.05 ▅▇▆▂▁
Gas&Oil 0 1 0.00 0.02 0.00 0.00 0.00 0.00 10.00 ▇▁▁▁▁
Geo 0 1 343950.43 136947.76 0.00 326860.63 389747.94 429947.43 564010.00 ▂▁▂▇▁
Hydro 0 1 1236247.18 481540.63 10602.00 972676.07 1316613.54 1592607.33 2363701.00 ▂▂▇▇▁
Solar 0 1 161.16 1492.40 0.00 0.00 0.00 0.00 23760.00 ▇▁▁▁▁
Wind 0 1 108670.67 87375.87 0.00 38355.62 93197.76 164547.30 516562.00 ▇▅▂▁▁
Wood 0 1 12234.28 6898.30 0.00 7410.00 15486.00 17330.00 20156.00 ▃▁▁▅▇
dv_year 0 1 2016.92 4.28 2010.00 2013.00 2017.00 2021.00 2024.00 ▇▇▇▇▇
dv_month 0 1 6.47 3.43 1.00 4.00 6.00 9.00 12.00 ▇▆▆▆▇
dv_hour 0 1 11.50 6.92 0.00 5.00 11.00 17.00 23.00 ▇▇▆▇▇
dv_total 0 1 2089850.68 769195.15 16628.18 1825026.58 2281057.91 2593708.25 3626574.00 ▂▁▅▇▁
dv_coal_gas 0 1 388331.52 240465.87 0.00 224730.25 377517.80 546313.09 1285566.13 ▆▇▅▁▁
dv_coal_gas_pc 0 1 16.85 9.73 0.00 10.70 16.91 22.99 92.89 ▇▆▁▁▁
dv_solar_wind 0 1 108831.83 87597.80 0.00 38480.32 93316.03 164700.51 531425.00 ▇▅▁▁▁
dv_solar_wind_pc 0 1 4.98 4.02 0.00 1.90 4.20 7.27 61.06 ▇▁▁▁▁
RENEWABLE 0 1 1701263.72 620149.02 12297.04 1496181.29 1840074.58 2118711.42 3062302.00 ▂▁▆▇▁
RENEWABLE_perc 0 1 83.14 9.74 7.11 76.99 83.08 89.30 100.00 ▁▁▁▆▇
WIND_perc 0 1 4.97 4.01 0.00 1.89 4.20 7.26 61.06 ▇▁▁▁▁
SOLAR_perc 0 1 0.01 0.06 0.00 0.00 0.00 0.00 1.20 ▇▁▁▁▁
HYDRO_perc 0 1 62.39 14.50 7.11 53.98 59.97 65.82 100.00 ▁▁▇▃▂
GEO_perc 0 1 15.23 6.79 0.00 13.04 16.08 19.25 34.68 ▂▃▇▂▁
WOOD_perc 0 1 0.54 0.33 0.00 0.31 0.63 0.76 1.29 ▅▂▇▃▁
GAS_perc 0 1 12.91 7.06 0.00 8.91 13.28 17.64 64.26 ▇▇▁▁▁
COAL_perc 0 1 3.94 4.97 0.00 0.00 3.03 6.39 75.43 ▇▁▁▁▁
DIESEL_perc 0 1 0.01 0.11 0.00 0.00 0.00 0.00 3.04 ▇▁▁▁▁
ratio 0 1 0.09 0.08 0.00 0.03 0.07 0.13 1.57 ▇▁▁▁▁
CARBON_INTENSITY 0 1 196.29 52.98 58.37 156.01 187.83 225.26 851.61 ▇▃▁▁▁

Variable type: POSIXct

skim_variable n_missing complete_rate min max median n_unique
dv_dateTime 0 1 2010-01-01 00:15:00 2024-10-31 23:45:00 2017-06-01 23:30:00 260034

9.3 R environment

Packages etc:

  • base R (R Core Team 2016)
  • bookdown (Xie 2016a)
  • data.table (Dowle et al. 2015)
  • ggplot2 (Wickham 2009)
  • here (Müller 2017)
  • hms (Müller 2018)
  • knitr (Xie 2016b)
  • lubridate (Grolemund and Wickham 2011)
  • rmarkdown (Allaire et al. 2018)

References

Allaire, JJ, Yihui Xie, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, Hadley Wickham, Joe Cheng, and Winston Chang. 2018. Rmarkdown: Dynamic Documents for r. https://CRAN.R-project.org/package=rmarkdown.
Dowle, M, A Srinivasan, T Short, S Lianoglou with contributions from R Saporta, and E Antonyan. 2015. Data.table: Extension of Data.frame. https://CRAN.R-project.org/package=data.table.
Grolemund, Garrett, and Hadley Wickham. 2011. “Dates and Times Made Easy with lubridate.” Journal of Statistical Software 40 (3): 1–25. http://www.jstatsoft.org/v40/i03/.
Müller, Kirill. 2017. Here: A Simpler Way to Find Your Files. https://CRAN.R-project.org/package=here.
———. 2018. Hms: Pretty Time of Day. https://CRAN.R-project.org/package=hms.
R Core Team. 2016. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
Staffell, Iain. 2017. “Measuring the Progress and Impacts of Decarbonising British Electricity.” Energy Policy 102 (March): 463–75. https://doi.org/10.1016/j.enpol.2016.12.037.
Staffell, Iain, and Stefan Pfenninger. 2018. “The Increasing Impact of Weather on Electricity Supply and Demand.” Energy 145 (February): 65–78. https://doi.org/10.1016/j.energy.2017.12.051.
Wickham, Hadley. 2009. Ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. http://ggplot2.org.
Xie, Yihui. 2016a. Bookdown: Authoring Books and Technical Documents with R Markdown. Boca Raton, Florida: Chapman; Hall/CRC. https://github.com/rstudio/bookdown.
———. 2016b. Knitr: A General-Purpose Package for Dynamic Report Generation in r. https://CRAN.R-project.org/package=knitr.