Important Note

Data Sources * certificates_2020: RYSHA FOUND THAT * authority_codes:https://public.opendatasoft.com/explore/dataset/georef-united-kingdom-local-authority-district/export/?disjunctive.ctry_code&disjunctive.ctry_name&disjunctive.rgn_code&disjunctive.rgn_name&disjunctive.ctyua_code&disjunctive.ctyua_name&disjunctive.lad_code&disjunctive.lad_name * incomes_2020: RYSHA FOUND THAT * housing_age: https://www.datadaptive.com/docs/Age%20Profiles%20of%20Housing%20Stock%20-%20User%20Guide.pdf * govt_spending_per_head: https://www.gov.uk/government/statistics/country-and-regional-analysis-2020/country-and-regional-analysis-november-2020 * average_house_size: https://assets.publishing.service.gov.uk/media/5f047a01d3bf7f2be8350262/Size_of_English_Homes_Fact_Sheet_EHS_2018.pdf * size:https://www.ons.gov.uk/datasets/TS050/editions/2021/versions/1 * fiscal_spending:https://www.gov.uk/government/statistics/dluhc-enabled-spend-statistics-2021-22-and-2022-23

# Group by local authority (smallest level of governance) and calculate averages
ratings_county <- certificates_2020 %>% 
  group_by(LOCAL_AUTHORITY) %>% 
  summarise(
    avg_energyeff_current = mean(CURRENT_ENERGY_EFFICIENCY),
    avg_energyeff_potential = mean(POTENTIAL_ENERGY_EFFICIENCY),
    avg_envt_impact_current = mean(ENVIRONMENT_IMPACT_CURRENT),
    avg_envt_impact_potential = mean(ENVIRONMENT_IMPACT_POTENTIAL),
    avg_CO2_emissions_current = mean(CO2_EMISSIONS_CURRENT),
    avg_CO2_emissions_potential = mean(CO2_EMISSIONS_POTENTIAL),
    avg_lighting_cost_current = mean(LIGHTING_COST_CURRENT),
    avg_lighting_cost_potential = mean(LIGHTING_COST_POTENTIAL),
    avg_heating_cost_current = mean(HEATING_COST_CURRENT),
    avg_heating_cost_potential = mean(HEATING_COST_POTENTIAL),
    avg_hot_water_cost_current = mean(HOT_WATER_COST_CURRENT),
    avg_hot_water_cost_potential = mean(HOT_WATER_COST_POTENTIAL),
    avg_floor_area = mean(TOTAL_FLOOR_AREA)
  ) %>%
  mutate(
    ENERGY_CONSUMPTION_DIFFERENTIAL = avg_energyeff_potential - avg_energyeff_current
  ) %>%
  arrange(desc(ENERGY_CONSUMPTION_DIFFERENTIAL))
# Merge data
merged_data <- merge(ratings_county, authority_codes, by.x = "LOCAL_AUTHORITY", by.y = "LOCAL_AUTHORITY") 
merged_data <- merge(merged_data, incomes_2020, by.x = "LOCAL_AUTHORITY", by.y = "Local authority code", all.x = TRUE)
merged_data <- merge(merged_data, housing_age, by.x = "LOCAL_AUTHORITY", by.y = "GEOCODE", all.x = TRUE)
# Plot thematic map- current energy efficiency
tmap_mode("view") # makes map interactive
your_data <- merged_data[!is.na(merged_data$Geo.Point), ]
your_data <- separate(your_data, Geo.Point, into = c("latitude_column", "longitude_column"), sep = ",")
coordinates <- st_as_sf(your_data, coords = c("longitude_column", "latitude_column"), crs = 4326)

breaks <- c(45,50,55,60,65,70)
colors <- c("blue", "cyan", "green","yellow","orange","red")

tm_shape(coordinates) +
  tm_bubbles(size = "avg_energyeff_current", 
             col = "avg_energyeff_current",
             breaks = breaks,
             palette = colors,
             title.size = 1, title.col = "black", title = "Avg Energy Efficiency Current") +
  tm_layout(legend.position = c("right", "bottom"))
# Plot thematic map- potential energy efficiency 
your_data <- merged_data[!is.na(merged_data$Geo.Point), ]
your_data <- separate(your_data, Geo.Point, into = c("latitude_column", "longitude_column"), sep = ",")
coordinates <- st_as_sf(your_data, coords = c("longitude_column", "latitude_column"), crs = 4326)

breaks <- c(70,75,80,85,90,95)
colors <- c("blue", "cyan", "green","yellow","orange","red")

tm_shape(coordinates) +
  tm_bubbles(size = "avg_energyeff_potential", 
             col = "avg_energyeff_potential",
             breaks = breaks,
             palette = colors,
             title.size = 1, title.col = "black", title = "Avg Energy Efficiency Potential") +
  tm_layout(legend.position = c("right", "bottom"))
# Plot thematic map-  energy efficiency differential
your_data <- merged_data[!is.na(merged_data$Geo.Point), ]
your_data <- separate(your_data, Geo.Point, into = c("latitude_column", "longitude_column"), sep = ",")
coordinates <- st_as_sf(your_data, coords = c("longitude_column", "latitude_column"), crs = 4326)

breaks <- c(10,13,16,19,22,25)
colors <- c("violet", "blue", "green","yellow","orange","red")

tm_shape(coordinates) +
  tm_bubbles(size = "ENERGY_CONSUMPTION_DIFFERENTIAL", 
             col = "ENERGY_CONSUMPTION_DIFFERENTIAL",
             breaks = breaks,
             palette = colors,
             title.size = 1, title.col = "black", title = "Avg Energy Efficiency Differential (unmet capacity for more energy-efficent housing)") +
  tm_layout(legend.position = c("right", "bottom"))

Map Analysis

merged_data_region <- merged_data %>% 
  group_by(Region.Name) %>% 
  summarise(
    avg_energyeff_current_region = mean(avg_energyeff_current),
    avg_energyeff_potential_region = mean(avg_energyeff_potential),
    avg_envt_impact_current_region = mean(avg_envt_impact_current),
    avg_envt_impact_potential_region = mean(avg_envt_impact_potential),
    avg_netincomes = mean(Disposable.Income),
    reg_BPPRE1900P = mean(BPPRE1900P),
    reg_BP190018P = mean(BP190018P),
    reg_BP191929P = mean(BP191929P),
    reg_BP193039P = mean(BP193039P),
    reg_BP194554P = mean(BP194554P),
    reg_BP195564P = mean(BP195564P),
    reg_BP196572P = mean(BP196572P),
    reg_BP197382P = mean(BP197382P),
    reg_BP198392P = mean(BP198392P),
    reg_BP199399P = mean(BP199399P),
    reg_BP200008P = mean(BP200008P),
    reg_BP200911P = mean(BP200911P),
    reg_BP201214P = mean(BP201214P),
    reg_BP201517P = mean(BP201517P),
    reg_BP201820P = mean(BP201820P)
  ) %>%
  mutate(
    ENERGY_CONSUMPTION_DIFFERENTIAL_REGION = avg_energyeff_potential_region - avg_energyeff_current_region
  ) %>%
  arrange(desc(ENERGY_CONSUMPTION_DIFFERENTIAL_REGION))


# Line chart
df_region <- merged_data_region %>%
  select(Region.Name, matches("^reg_BP"))

dfl_region <- melt(df_region, id.vars = "Region.Name")
dfl_region$period <- str_extract(dfl_region$variable, "\\d+")
dfl_region$start <- as.numeric(str_sub(dfl_region$period, 1, 4))
dfl_region$end <- as.numeric(paste0(str_sub(dfl_region$period, 1, 2), str_sub(dfl_region$period, 5, 6)))
dfl_region$start[dfl_region$end == 19] <- 1890
dfl_region$end[dfl_region$end == 19] <- 1899
dfl_region$mid <- dfl_region$start + (dfl_region$end - dfl_region$start) / 2

ggplot(data = dfl_region, aes(x = mid, y = value, group = Region.Name)) +
  geom_line(aes(color = Region.Name)) +
  labs(x = "Year of Construction", y = "% of Housing in Region")

dfl_region <- dfl_region %>%
  mutate(age_2020 = 2020 - mid)

dfl_summary_region <- dfl_region %>%
  group_by(Region.Name) %>%
  summarise(total_houses_region = sum(value),
            weighted_age_sum_region = sum(age_2020 * value)) %>%
  mutate(average_age_region = weighted_age_sum_region / total_houses_region)
# Government spending analysis
region <- c("North East", "North West", "Yorkshire", "East Midla", "West Midla", "East", "London", "South East", "South West", "Wales")
govt_spending_per_head <- c(10285, 10204, 9401, 8879, 9570, 8991, 10835, 8919, 9193, 10929)
average_house_size <- c(89, 90, 89, 96, 94, 100, 84, 102, 101, 101) 
spending_frame <- data.frame(Region = region, `Government Spending Per Head` = govt_spending_per_head / 1000, 'Average House Size' = average_house_size)
all_data_region <- merge(spending_frame, merged_data_region, by.x = "Region", by.y = "Region.Name", all.x = TRUE)
all_data_final_region <- merge(all_data_region, dfl_summary_region, by.x = "Region", by.y = "Region.Name", all.x = TRUE)
# Plotting
ggplot(data = all_data_final_region, aes(x = Government.Spending.Per.Head, y = avg_energyeff_current_region, label = Region)) +
  geom_point(color = "blue", size = 3) +
  geom_text(nudge_x = 0.2, nudge_y = 0.2, size = 3) +
  labs(title = "Energy Efficiency vs Government Spending",
       x = "Government Spending Per Head (in GBP thousands)",
       y = "Average Energy Efficiency(%)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = Government.Spending.Per.Head, y = avg_netincomes, label = Region)) +
  geom_point(color = "green", size = 3) +
  geom_text(nudge_x = 0.2, nudge_y = 0.2, size = 3) +
  labs(title = "Average Net Income vs Government Spending",
       x = "Government Spending Per Head (in GBP thousands)",
       y = "Average Net Income (GBP)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = avg_netincomes, y = avg_energyeff_current_region, label = Region)) +
  geom_point(color = "orange", size = 3) +
  geom_text(aes(label = Region), nudge_x = 0.5, nudge_y = 0.5, size = 3) +
  labs(title = "Energy Efficiency vs Average Net Income",
       x = "Average Net Income (GBP)",
       y = "Average Energy Efficiency (%)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = avg_netincomes, y = average_age_region, label = Region)) +
  geom_point(color = "red", size = 3) +
  geom_text(nudge_x = 0.5, nudge_y = 0.5, size = 3) +
  labs(title = "Average Property Age vs Average Net Income",
       x = "Average Net Income (GBP)",
       y = "Average Property Age (years)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = average_age_region, y = avg_energyeff_current_region, label = Region)) +
  geom_point(color = "purple", size = 3) +
  geom_text(nudge_x = 0.5, nudge_y = 0.5, size = 3) +
  labs(title = "Energy Efficiency (%) vs Average Property Age (years)",
       x = "Average Property Age (years)",
       y = "Average Energy Efficiency (%)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = Average.House.Size, y = avg_energyeff_current_region, label = Region)) +
  geom_point(color = "brown", size = 3) +
  geom_text(nudge_x = 0.5, nudge_y = 0.5, size = 3) +
  labs(title = "Energy Efficiency vs Average Property Size (m^2)",
       x = "Average Property Size (m^2)",
       y = "Average Energy Efficiency (%)") +
  theme_minimal()

ggplot(data = all_data_final_region, aes(x = Average.House.Size, y = average_age_region, label = Region)) +
  geom_point(color = "cyan", size = 3) +
  geom_text(nudge_x = 0.5, nudge_y = 0.5, size = 3) +
  labs(title = "Average Property Age vs Average Property Size (m^2)",
       x = "Average Property Size (m^2)",
       y = "Average Property Age (years)") +
  theme_minimal()

## Regional Analysis

# Regression analysis
merged_data_authority <- merged_data %>% 
  group_by(LOCAL_AUTHORITY) %>% 
  summarise(
    avg_energyeff_current_aut = mean(avg_energyeff_current),
    avg_energyeff_potential_aut = mean(avg_energyeff_potential),
    avg_envt_impact_current_aut = mean(avg_envt_impact_current),
    avg_envt_impact_potential_aut = mean(avg_envt_impact_potential),
    avg_netincomes = mean(Disposable.Income),
    avg_CO2_emissions_current_aut = mean(avg_CO2_emissions_current),
    avg_CO2_emissions_potential_aut = mean(avg_CO2_emissions_current),
    avg_lighting_cost_current_aut = mean(avg_lighting_cost_current),
    avg_lighting_cost_potential_aut = mean(avg_lighting_cost_potential),
    avg_heating_cost_current_aut = mean(avg_heating_cost_current),
    avg_heating_cost_potential_aut = mean(avg_heating_cost_potential),
    avg_hot_water_cost_current_aut = mean(avg_hot_water_cost_current),
    avg_hot_water_cost_potential_aut = mean(avg_hot_water_cost_potential),
    avg_floor_size_aut = mean(avg_floor_area),
    reg_BPPRE1900P = mean(BPPRE1900P),
    reg_BP190018P = mean(BP190018P),
    reg_BP191929P = mean(BP191929P),
    reg_BP193039P = mean(BP193039P),
    reg_BP194554P = mean(BP194554P),
    reg_BP195564P = mean(BP195564P),
    reg_BP196572P = mean(BP196572P),
    reg_BP197382P = mean(BP197382P),
    reg_BP198392P = mean(BP198392P),
    reg_BP199399P = mean(BP199399P),
    reg_BP200008P = mean(BP200008P),
    reg_BP200911P = mean(BP200911P),
    reg_BP201214P = mean(BP201214P),
    reg_BP201517P = mean(BP201517P),
    reg_BP201820P = mean(BP201820P)
  ) %>%
  mutate(
    ENERGY_CONSUMPTION_DIFFERENTIAL_AUT = avg_energyeff_potential_aut - avg_energyeff_current_aut
  ) %>%
  arrange(desc(ENERGY_CONSUMPTION_DIFFERENTIAL_AUT))

# Regression analysis
reg_income <- lm(avg_energyeff_current_aut ~ avg_netincomes, merged_data_authority)
reg_income
## 
## Call:
## lm(formula = avg_energyeff_current_aut ~ avg_netincomes, data = merged_data_authority)
## 
## Coefficients:
##    (Intercept)  avg_netincomes  
##      6.136e+01       1.554e-04
# Bar chart
df <- merged_data_authority %>%
  select(LOCAL_AUTHORITY, matches("^reg_BP"))

dfl <- melt(df, id.vars = "LOCAL_AUTHORITY")
dfl$period <- str_extract(dfl$variable, "\\d+")
dfl$start <- as.numeric(str_sub(dfl$period, 1, 4))
dfl$end <- as.numeric(paste0(str_sub(dfl$period, 1, 2), str_sub(dfl$period, 5, 6)))
dfl$start[dfl$end == 19] <- 1890
dfl$end[dfl$end == 19] <- 1899
dfl$mid <- dfl$start + (dfl$end - dfl$start) / 2


dfl <- dfl %>%
  mutate(age_2020 = 2020 - mid)

dfl_summary <- dfl %>%
  group_by(LOCAL_AUTHORITY) %>%
  summarise(total_houses = sum(value),
            weighted_age_sum = sum(age_2020 * value)) %>%
  mutate(average_age = weighted_age_sum / total_houses)

all_data <- merge(merged_data_authority, dfl_summary, by.x = "LOCAL_AUTHORITY", by.y = "LOCAL_AUTHORITY", all.x = TRUE)

size <- read_excel("C:/Users/antho/Downloads/housing_size.xlsx")

size <- size %>%
  group_by(LOCAL_AUTHORITY) %>%
  summarise(total_rooms = sum(Observation),
            weighted_room_sum = sum(Rooms*Observation)) %>%
  mutate(average_size = weighted_room_sum / total_rooms)

all_data_final <- merge(all_data,size,by.X="LOCAL_AUTHORITY",by.y="LOCAL_AUTHORITY",all.x=TRUE)
fiscal_spending <- read.csv("C:/Users/antho/Downloads/fiscal_spending_DLUHC.csv")
all_data_final <- merge(all_data_final,fiscal_spending,by.x="LOCAL_AUTHORITY",by.y="LAD22CD")


library(jtools)
reg1 <- lm(avg_energyeff_current_aut ~ average_age, data = all_data_final)
reg2 <- lm(avg_energyeff_current_aut ~ average_age + avg_floor_size_aut, data = all_data_final)
reg3 <- lm(avg_energyeff_current_aut ~ average_age + avg_floor_size_aut + avg_lighting_cost_current_aut, data = all_data_final)
reg4 <- lm(avg_energyeff_current_aut ~ average_age + avg_floor_size_aut + avg_lighting_cost_current_aut + avg_hot_water_cost_current_aut, data = all_data_final)
reg5<- lm(avg_energyeff_current_aut ~ average_age + avg_floor_size_aut + avg_lighting_cost_current_aut + avg_hot_water_cost_current_aut + avg_heating_cost_current_aut, data = all_data_final)

export_summs(reg1, reg2, reg3, reg4, reg5, model.names = c("Age", "Age & Size ","Age & Size & Lighting Cost", "Age & Size & Lighting Cost & Hot Water Cost", "Age & Size & Lighting Cost & Heating Cost & Hot Water Cost")) 
AgeAge & Size Age & Size & Lighting CostAge & Size & Lighting Cost & Hot Water CostAge & Size & Lighting Cost & Heating Cost & Hot Water Cost
(Intercept)72.79 ***87.18 ***98.66 ***103.93 ***88.24 ***
(0.12)   (0.20)   (0.22)   (0.16)   (0.14)   
average_age-0.10 ***-0.15 ***-0.14 ***-0.14 ***-0.06 ***
(0.00)   (0.00)   (0.00)   (0.00)   (0.00)   
avg_floor_size_aut       -0.13 ***0.11 ***0.11 ***0.14 ***
       (0.00)   (0.00)   (0.00)   (0.00)   
avg_lighting_cost_current_aut              -0.41 ***-0.31 ***-0.13 ***
              (0.00)   (0.00)   (0.00)   
avg_hot_water_cost_current_aut                     -0.10 ***-0.06 ***
                     (0.00)   (0.00)   
avg_heating_cost_current_aut                            -0.02 ***
                            (0.00)   
N22097       22097       22097       22097       22097       
R20.12    0.34    0.49    0.74    0.89    
*** p < 0.001; ** p < 0.01; * p < 0.05.
reg6 <- lm(avg_energyeff_current_aut ~ avg_netincomes, data = all_data_final)
#just testing to see that environmental impact should have a relationship with energy efficiency, which is does
summary(reg6)
## 
## Call:
## lm(formula = avg_energyeff_current_aut ~ avg_netincomes, data = all_data_final)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -25.8100  -1.2315   0.0883   1.6595   9.9608 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    6.276e+01  1.386e-01   452.8   <2e-16 ***
## avg_netincomes 1.156e-04  4.551e-06    25.4   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.868 on 21225 degrees of freedom
##   (870 observations deleted due to missingness)
## Multiple R-squared:  0.02949,    Adjusted R-squared:  0.02944 
## F-statistic:   645 on 1 and 21225 DF,  p-value: < 2.2e-16

Regression Analysis

lm(avg_energyeff_current_aut ~ avg_heating_cost_current_aut, data = all_data_final)

Caveats

  • While our data analysis endeavours to provide valuable insights into energy efficiency and its determinants across UK regions, several caveats must be considered to interpret the findings accurately.
  • Firstly, it’s crucial to acknowledge that not all houses have Energy Performance Certificates (EPCs), resulting in incomplete coverage of the housing stock. This limitation introduces a potential bias, as the absence of EPC data may disproportionately affect certain types of properties, such as older houses. Indeed, older houses are less likely to have EPCs, thus skewing the representation of energy efficiency in the dataset.
  • Moreover, when calculating average ages of housing stock, a variable set for pre-1900 construction was used, treating all properties built before 1900 equally, regardless of their actual construction dates. This approach may overlook significant variations in the ages of older properties, potentially misrepresenting the distribution of housing ages.
  • Additionally, while government spending per capita provides insights into overall public expenditure, it’s essential to recognize that this metric, when studied at the regional level in the dataframe ‘government_spending_per_head’, encompasses various sectors and initiatives beyond housing and environmental concerns. Consequently, interpreting its relationship with energy efficiency requires caution, as it may not accurately reflect targeted investments in energy-efficient infrastructure or policies.