Assessing Cost-of-Living Impacts on
Electricity Customers
by Dane Tipene
2025-02-28
Project Overview
Introduction
A major headline across Victoria highlights the rising cost of
living, with more households struggling to pay bills and facing
financial hardship.
This analysis examines performance indicators from the Compliance and
Performance Reporting Guideline (CPRG) to assess whether there is
evidence that cost-of-living pressures are driving financial hardship
among residential electricity customers. The findings will provide
data-driven insights to inform policy reforms aimed at strengthening
consumer protections and reducing financial strain.
Objectives
Assess Disconnection Risk – Are more residential
electricity customers at risk of being disconnected (received a
disconnection notice) or being disconnected because of non-payment of
their bills?
Analyse Arrears Growth – Are arrears (debts)
increasing for residential electricity customers who receive financial
assistance in the form of tailored assistance?
Measure Tailored Assistance Uptake – Are more
residential electricity customers accessing tailored financial
assistance?
By the end of this analysis, we will have a clear understanding of
how affordability challenges impact electricity customers, helping
decision-makers respond proactively.
Impact
The insights from this analysis will support targeted policy
recommendations to help both consumers and energy providers navigate
financial challenges:
Enhanced Consumer Protections - If affordability
issues are worsening, regulators may introduce stronger safeguards to
prevent unnecessary disconnections.
Improved Assistance Programs - Identifying trends
in arrears and financial assistance uptake can help optimize support
mechanisms for vulnerable customers.
Retailer Stability & Market Resilience -
Understanding arrears growth and disconnection patterns will allow
retailers to anticipate risks and adapt their strategies
accordingly.
By providing data-driven evidence, this analysis will inform
decision-making for policymakers, regulators, and energy retailers,
ensuring that financially vulnerable customers receive the necessary
support.
Note:This report utilizes toggle
buttons to enhance readability, allowing stakeholders to easily digest
key insights while providing the option to explore technical details as
needed.
Data Understanding
Data Source
The dataset used in this analysis comes from the Essential Services
Commission’s Compliance and Performance Reporting Guidelines (CPRG). It
contains monthly performance indicators reported by energy retailers to
track customer affordability and financial distress in the Victorian
electricity market. The data is reported separately for electricity and
gas, with customer and retailer segmentation by size (small, medium,
large).
Performance Indicators
Below are the key performance indicators used in this analysis,
categorized by focus area.
Indicator Code
Description
D050A
Residential accounts disconnected for non-payment,
excluding vacant premises and incomplete disconnections.
D140
Residential accounts disconnected for non-payment that
did not receive tailored or standard assistance in the
last six months.
D161(a)
Residential accounts disconnected for non-payment with
arrears below $300 (including zero or credit).
D161(b)
Residential accounts disconnected for non-payment with
arrears between $300 and $999.
D161(c)
Residential accounts disconnected for non-payment with
arrears between $1,000 and $1,999.
D161(d)
Residential accounts disconnected for non-payment with
arrears between $2,000 and $4,999.
D161(e)
Residential accounts disconnected for non-payment with
arrears above $5,000.
D170(a)
Reminder notices issued to residential accounts for
unpaid bills where the outstanding amount is
over $300.
D170(b)
Disconnection warning notices issued to residential
accounts with an outstanding amount over $300.
Indicator Code
Description
AR031(a)
Residential accounts that started tailored assistance with arrears
below $55 (including credits).
AR031(b)
Residential accounts that started tailored assistance with arrears
between $55 and $999.
AR031(c)
Residential accounts that started tailored assistance with arrears
between $1,000 and $1,999.
AR031(d)
Residential accounts that started tailored assistance with arrears
between $2,000 and $2,999.
AR031(e)
Residential accounts that started tailored assistance with arrears
between $3,000 and $4,999.
AR031(f)
Residential accounts that started tailored assistance with arrears
above $5,000.
Indicator Code
Description
AS022(a)
Residential accounts on tailored assistance that can
pay at least their ongoing usage.
AS022(b)
Residential accounts on tailored assistance that
cannot pay their ongoing usage.
AS031(a)
Residential accounts on tailored assistance with an
electricity concession that can pay at least their
ongoing usage.
AS031(b)
Residential accounts on tailored assistance with an
electricity concession that cannot pay
their ongoing usage.
AS061
Residential accounts that exited tailored assistance
with arrears of $0 or a credit balance.
AS080
Residential accounts removed from tailored assistance
due to non-compliance with payment or energy use
requirements.
During the data investigation phase, the dataset was explored to
identify potential cleaning requirements and gather key insights before
proceeding with data processing. Below are the initial observations:
1. Unique Values & Data Distribution
Fuel Type: All values in the dataset are
Electricity, meaning there is no need to filter out gas-related
records.
Retailers: The dataset contains 51 retailers (ID
range 0-52), with RET_47 missing.
Customer Type: Found 4 unique values – Large
business, NULL, Residential, Small business.
Present in the customer_type and
retailer_size columns.
All NULL values in customer_type are linked to B220,
which falls outside the scope of our assigned KPIs and does not impact
the analysis.
NULL values in retailer_size appear in 9.41% to 13.66%
of associated KPIs, several of which are relevant to this analysis.
However, since retailer_size is not a critical factor in
assessing cost-of-living impacts on bill payments, these values will be
retained to prevent unnecessary data loss.
# Unique value check across relevant columns
sorted_unique_values <- customer_data %>%
select(fuel, retailer_id, customer_type, retailer_size) %>%
map(~ sort(unique(.)))
sorted_unique_values
Impact: Resolving this issue requires removing
D161(a–e) and relabeling D162(a–e) as D161(a-e), resulting in a 28.67%
reduction in the D161/D162 disconnections data and 1.36% total dataset
reduction.
Final Check: All other high value
indicator_common_ids were verified and match CPRG
requirements.
# CPRG discrepancy noticed, inspect further
# Define the target indicator_common_id values
target_indicators <- c("D161(a)", "D161(b)", "D161(d)", "D161(e)",
"D162(a)", "D162(b)", "D162(c)", "D162(d)", "D162(e)")
# Filter the dataset
filtered_data <- customer_data %>%
filter(indicator_common_id %in% target_indicators)
# Display the filtered dataframe using filtered_data
# For the output of the RMD file, head() is used
head(filtered_data)
# Major discrepancy found. Calculate percentage of data if all D161 rows are to be removed
# Define the target indicator values to be removed
remove_indicators <- c("D161(a)", "D161(b)", "D161(d)", "D161(e)")
# Count total rows **before removal** (entire dataset)
total_rows <- nrow(customer_data)
# Count total rows associated with **D161 & D162** (before removal)
total_d161_d162 <- customer_data %>%
filter(grepl("^D161|^D162", indicator_common_id)) %>% # Selects all D161 & D162 rows
nrow()
# Count how many rows match the removal criteria (D161(a–e))
rows_to_remove <- customer_data %>%
filter(indicator_common_id %in% remove_indicators) %>%
nrow()
# Calculate percentage of data removed from **entire dataset**
percent_removed_total <- (rows_to_remove / total_rows) * 100
# Calculate percentage of data removed from **D161 & D162 records only**
percent_removed_d161_d162 <- (rows_to_remove / total_d161_d162) * 100
# Print results
cat("Percentage of data removed from total dataset:", round(percent_removed_total, 2), "%\n")
## Percentage of data removed from total dataset: 1.36 %
cat("Percentage of data removed from D161 & D162 records:", round(percent_removed_d161_d162, 2), "%\n")
## Percentage of data removed from D161 & D162 records: 28.67 %
# Define the target indicators
target_indicators <- c("D161(a)", "D161(b)", "D161(d)", "D161(e)")
# Get value range (min & max) for each indicator
value_ranges <- customer_data %>%
filter(indicator_common_id %in% target_indicators) %>%
group_by(indicator_common_id) %>%
summarise(
min_value = min(value, na.rm = TRUE),
max_value = max(value, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(indicator_common_id) # Sort output in ascending order
# Display the result
value_ranges
# Create the boxplot
ggplot(customer_data, aes(y = value)) +
geom_boxplot(outlier.colour = "red", outlier.shape = 16, outlier.size = 2) +
geom_hline(yintercept = lower_bound, linetype = "dashed", color = "#236092") + # Lower Bound
geom_hline(yintercept = upper_bound, linetype = "dashed", color = "#236092") + # Upper Bound
labs(title = "Boxplot of Outliers",
y = "Value",
x = "") +
theme_minimal()
# Find all rows where 'value' is less than 0 (excluding zero)
negative_values <- customer_data %>%
filter(value < 0)
# Display the result
negative_values
## fuel yearmonth retailer_id indicator_common_id
## 1 Electricity 202306 RET_48 AR060
## 2 Electricity 202311 RET_48 AR060
## 3 Electricity 202309 RET_48 AR060
## 4 Electricity 202310 RET_48 AR060
## 5 Electricity 202312 RET_48 AR060
## 6 Electricity 202308 RET_48 AR060
## 7 Electricity 202401 RET_48 AR060
## indicator_common_name customer_type value retailer_size
## 1 SmlBus_PaymentAssistance_AvgArrears Small business -2.0000 Large
## 2 SmlBus_PaymentAssistance_AvgArrears Small business -128.2339 Large
## 3 SmlBus_PaymentAssistance_AvgArrears Small business -129.0000 Large
## 4 SmlBus_PaymentAssistance_AvgArrears Small business -144.0930 Large
## 5 SmlBus_PaymentAssistance_AvgArrears Small business -177.8572 Large
## 6 SmlBus_PaymentAssistance_AvgArrears Small business -178.0000 Large
## 7 SmlBus_PaymentAssistance_AvgArrears Small business -248.5968 Large
Data Cleaning
Action Steps
Correct mislabeled indicators:
Remove D161(a–e) records, as their values do not align with CPRG
definitions, causing a 28.67% reduction in D161/D162 disconnections data
and 1.36% total dataset reduction.
Relabel D162(a–e) as D161(a–e) to align with CPRG standards.
Transform yearmonth for better time-series
analysis:
Split the yearmonth column (YYYYMM format) into separate Year and
Month columns.
Create a standardized Date column by combining the Year and Month
columns into a proper YYYY-MM-DD format, setting the day as the first of
the month for consistency.
Filter dataset to focus on relevant indicators:
Create a cleaned dataframe (customer_data_cleaned)
containing only performance indicators for disconnections, arrears, and
financial assistance uptake, including D050A, D140, D161(a to e), D170(a
& b, AR031(a to f), ASO22(a & b), ASO31(a & b), AS061,
AS080.
Exclude rows where customer_type is Large business, NULL, or Small
business, as they do not pertain to residential customers.
# Remove rows where indicator_common_id is D161(a–e)
customer_data_cleaned <- customer_data %>%
filter(!indicator_common_id %in% c("D161(a)", "D161(b)", "D161(c)", "D161(d)", "D161(e)"))
# Convert yearmonth to Year and Month columns
customer_data_cleaned <- customer_data_cleaned %>%
mutate(
year = as.integer(substr(yearmonth, 1, 4)), # Extract first 4 digits as Year
month = as.integer(substr(yearmonth, 5, 6)) # Extract last 2 digits as Month
) %>%
select(-yearmonth) # Remove original yearmonth column
# Convert Year and Month into a proper Date format
customer_data_cleaned <- customer_data_cleaned %>%
mutate(date = as.Date(paste(year, month, "01", sep = "-"), format = "%Y-%m-%d"))
To answer the question, “Are more residential electricity
customers at risk of being disconnected (received a disconnection
notice) or being disconnected because of non-payment of their
bills?”, this section examines whether residential
electricity customers are increasingly at risk of disconnection due to
unpaid bills. The analysis focuses on two key areas:
Risk of Disconnection – Trends in disconnection
warning notices to assess whether more households are approaching
disconnection.
Actual Disconnections – Trends in service
disconnections due to non-payment, including variations across arrears
levels.
By evaluating these indicators over time, this analysis aims to
determine whether financial hardship is escalating and to provide
insights that can inform consumer protection measures and support
programs.
1. Reminder & Disconnection Warning Notices
“Are Reminder Notices (D170(a)) and Disconnection Warning Notices
(D170(b)) Increasing Over Time?”
Indicator Code
Description
D170(a)
Reminder notices issued to residential accounts for
unpaid bills where the outstanding amount is
over $300.
D170(b)
Disconnection warning notices issued to residential
accounts with an outstanding amount over $300.
# Code for Line Plot
# Filter dataset for Reminder Notices (D170(a)) and Disconnection Warning Notices (D170(b))
df_notices <- customer_data_cleaned %>%
filter(indicator_common_id %in% c("D170(a)", "D170(b)")) %>%
mutate(indicator_common_id = case_when(
indicator_common_id == "D170(a)" ~ "Reminder Notices",
indicator_common_id == "D170(b)" ~ "Warning Notices"
))
# Aggregate total notices per month
df_notices_agg <- df_notices %>%
group_by(date, indicator_common_id) %>%
summarise(total_notices = sum(value, na.rm = TRUE), .groups = "drop")
# Define color scheme for Essential Services Commission
esc_colors <- c("Reminder Notices" = "#236092", "Warning Notices" = "#a4bdcf")
# Create the time-series line chart with consistent formatting
ggplot(df_notices_agg, aes(x = date, y = total_notices, color = indicator_common_id, group = indicator_common_id)) +
geom_line(linewidth = 1) + # Standard linewidth
geom_point(size = 2) + # Standard geom_point size
scale_color_manual(values = esc_colors) + # Apply Essential Services Commission colors
labs(title = "Trends in Reminder Notices and Warning Notices",
x = "Year-Month",
y = "Number of Notices Issued",
color = "Notice Type") +
theme_minimal() +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Standard x-axis rotation
# Code for summary metrics table
# Aggregate total notices per month
df_notices_agg <- customer_data_cleaned %>%
filter(indicator_common_id %in% c("D170(a)", "D170(b)")) %>%
group_by(date, indicator_common_id) %>%
summarise(total_notices = sum(value, na.rm = TRUE), .groups = "drop") %>%
arrange(date)
# Calculate month-over-month (MoM) change
df_notices_agg <- df_notices_agg %>%
group_by(indicator_common_id) %>%
mutate(mom_change = total_notices - lag(total_notices)) %>%
ungroup()
# Compute first and last values for percentage change
percentage_change <- df_notices_agg %>%
group_by(indicator_common_id) %>%
summarise(
first_value = first(total_notices),
last_value = last(total_notices),
total_percentage_change = ifelse(first_value == 0, NA, ((last_value - first_value) / first_value) * 100),
.groups = "drop"
)
# Compute summary statistics
summary_metrics <- df_notices_agg %>%
group_by(indicator_common_id) %>%
summarise(
total_notices_issued = sum(total_notices, na.rm = TRUE),
avg_monthly_change = mean(mom_change, na.rm = TRUE),
.groups = "drop"
) %>%
left_join(percentage_change, by = "indicator_common_id") # Merge percentage change
# Display the summary_metrics table
print(summary_metrics, width = Inf)
Key Insights
Yes, the data reveals a significant rise in reminder notices for
unpaid bills, while disconnection warnings have increased at a much
slower pace.
Reminder notices (D170(a)) have increased by 46.4% over the analysis
period, with an average of 656 additional notices issued each month.
This suggests a growing number of households struggling to pay on
time.
Disconnection warning notices (D170(b)) have increased by only 7.4%,
with an average increase of 39 per month. This indicates that while more
customers are missing payments, fewer are reaching the final warning
stage.
The gap between reminder notices and disconnection warnings is
widening, suggesting that some households are able to resolve overdue
bills before facing service disconnection.
2. Trends in Actual Disconnections
“Are Actual Disconnections Increasing? (D050A, D140,
D161)”
Indicator Code
Description
D050A
Residential accounts disconnected for non-payment,
excluding vacant premises and incomplete disconnections.
D140
Residential accounts disconnected for non-payment that
did not receive tailored or standard assistance in the
last six months.
D161(a)
Residential accounts disconnected for non-payment with
arrears below $300 (including zero or credit).
D161(b)
Residential accounts disconnected for non-payment with
arrears between $300 and $999.
D161(c)
Residential accounts disconnected for non-payment with
arrears between $1,000 and $1,999.
D161(d)
Residential accounts disconnected for non-payment with
arrears between $2,000 and $4,999.
D161(e)
Residential accounts disconnected for non-payment with
arrears above $5,000.
No, actual disconnections are not increasing overall. While
disconnections peaked in 2022, they have declined over time but remain
volatile, with fluctuations suggesting ongoing financial instability
rather than a consistent upward trend.
Disconnections have decreased since early-2022 but show
fluctuations, indicating that financial hardship remains a concern.
Households with arrears between $300 and $1,999 face the highest
risk of disconnection, making them a critical intervention group.
High-arrears households ($1,000+) are more frequently disconnected,
suggesting larger overdue balances correlate with longer-term financial
distress.
Disconnections for customers without financial assistance closely
mirror overall disconnection trends, indicating that support programs
may not be significantly reducing disconnections or that many at-risk
customers are not accessing available assistance.
Customers with arrears under $300 rarely face disconnection,
reinforcing that small overdue amounts seldom lead to service loss.
3. Gap Analysis Between Notices & Disconnections
“What is the gap between reminder notices (D170a), disconnection
warning notices (D170b), and actual disconnections (D050A)?”
Indicator Code
Description
D050A
Residential accounts disconnected for non-payment,
excluding vacant premises and incomplete disconnections.
D170(a)
Reminder notices issued to residential accounts for
unpaid bills where the outstanding amount is
over $300.
D170(b)
Disconnection warning notices issued to residential
accounts with an outstanding amount over $300.
### Plot Code
### Aggregate Data for All 3 Notice Types
# Filter dataset for Reminder Notices (D170a), Warning Notices (D170b), and Disconnections (D050A)
df_notices_disconnections <- customer_data_cleaned %>%
filter(indicator_common_id %in% c("D170(a)", "D170(b)", "D050A")) %>%
mutate(notice_type = case_when(
indicator_common_id == "D170(a)" ~ "Reminder Notices",
indicator_common_id == "D170(b)" ~ "Disconnection Warnings",
indicator_common_id == "D050A" ~ "Disconnected"
))
# Aggregate total values per month
df_notices_disconnections_agg <- df_notices_disconnections %>%
group_by(date, notice_type) %>%
summarise(total_count = sum(value, na.rm = TRUE), .groups = "drop")
### Plot 1
# Plot Reminder Notices, Warning Notices, and Disconnections over time
p1 <- ggplot(df_notices_disconnections_agg, aes(x = date, y = total_count, color = notice_type, group = notice_type)) +
geom_line(linewidth = 1) +
geom_point(size = 2) +
scale_color_manual(values = c("Reminder Notices" = "#236092",
"Disconnection Warnings" = "#a4bdcf",
"Disconnected" = "#cb0456")) +
labs(title = "Reminder Notices, Warning Notices, and Disconnections Over Time",
x = "Year-Month",
y = "Number of Accounts",
color = "Notice Type") +
theme_minimal() +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
### Plot 2
# Pivot wider to calculate gaps
df_notices_wide <- df_notices_disconnections_agg %>%
pivot_wider(names_from = notice_type, values_from = total_count, values_fill = 0) %>%
rename(
reminder_notices = `Reminder Notices`,
disconnection_warnings = `Disconnection Warnings`,
disconnections = `Disconnected`
) %>%
mutate(
reminder_warning_gap = reminder_notices - disconnection_warnings,
warning_disconnection_gap = disconnection_warnings - disconnections
)
# Convert back to long format for plotting
df_notices_gaps <- df_notices_wide %>%
select(date, reminder_warning_gap, warning_disconnection_gap) %>%
pivot_longer(cols = -date, names_to = "gap_type", values_to = "gap_value")
# Plot the gaps over time
p2 <- ggplot(df_notices_gaps, aes(x = date, y = gap_value, color = gap_type, group = gap_type)) +
geom_line(linewidth = 1) +
geom_point(size = 2) +
scale_color_manual(values = c("reminder_warning_gap" = "#236092",
"warning_disconnection_gap" = "#cb0456")) +
labs(title = "Gap Between Notices and Disconnections Over Time",
x = "Year-Month",
y = "Gap Size (Accounts)",
color = "Gap Type") +
theme_minimal() +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Arrange plots side by side
p1 + p2 + plot_layout(ncol = 1)
### Table Code
### Table 1
# Create summary table for notices and disconnections
table_notices_disconnections <- df_notices_disconnections_agg %>%
group_by(notice_type) %>%
summarise(
min_value = min(total_count, na.rm = TRUE),
max_value = max(total_count, na.rm = TRUE),
first_date = first(date),
first_value = first(total_count),
last_date = last(date),
last_value = last(total_count),
.groups = "drop"
)
### Table 2
# Create summary table for gaps between notices and disconnections
table_notices_gaps <- df_notices_gaps %>%
group_by(gap_type) %>%
summarise(
min_value = min(gap_value, na.rm = TRUE),
max_value = max(gap_value, na.rm = TRUE),
first_date = first(date),
first_value = first(gap_value),
last_date = last(date),
last_value = last(gap_value),
.groups = "drop"
)
# Print tables
print(table_notices_disconnections, width = Inf)
print(table_notices_gaps, width = Inf)
Key Insights
The gap between reminder notices (D170a), disconnection warnings
(D170b), and actual disconnections (D050A) has widened over time,
indicating that most overdue accounts do not escalate to
disconnection.
Reminder notices far outnumber both disconnection warnings and
actual disconnections, showing that most customers do not progress
beyond initial notices.
The reminder-warning gap peaked at 66,101 accounts, suggesting that
many customers resolve arrears or enter payment plans before reaching
the warning stage.
The warning-disconnection gap remains stable, with 19,480 more
accounts receiving a final warning than being disconnected, reinforcing
that few customers experience actual service termination.
Overall, disconnections have declined by 54.8% and remain low.
4. Additional Insights: Retailer Breakdown
Key Insights
The number of retailers issuing disconnection notices and actual
disconnections has declined over time.
Large retailers dominate disconnection notices, issuing close to 2.3
million total notices, but actual disconnections remain low.
Warnings far exceed disconnections, indicating most at-risk
customers avoid service termination.
Top retailers (RET_15, RET_01) issue the most disconnection
warnings, but disconnections remain minimal.
“Are more residential electricity customers at risk of being
disconnected (received a disconnection notice) or actually being
disconnected due to non-payment?”
📌 More customers are at risk, but actual disconnections
remain low.
Despite a 46.4% surge in reminder notices, actual disconnections
remain low, indicating that while more households are struggling to pay
on time, most do not progress to disconnection. Disconnection warnings
have risen at a much slower rate (+7.4%), and the widening gap between
notices and disconnections suggests that many customers are resolving
overdue balances before service termination. Customers with arrears
between $300 and $1,999 face the highest disconnection risk,
particularly those owing $1,000+, but relatively few are ultimately
disconnected.
Large retailers issue the majority of notices, yet few follow through
with disconnections, indicating that a significant number of overdue
customers avoid service loss—whether through payments, retailer
policies, or other factors. However, disconnections among customers
without financial assistance closely mirror overall trends, suggesting
that either support programs are not significantly reducing
disconnections, or many at-risk customers are not accessing available
assistance. This raises the need to evaluate how effectively financial
support programs prevent service terminations and whether outreach or
eligibility adjustments are necessary.
Metric
Value
Reminder Notices Increase (D170a)
+46.4%
Disconnection Warnings Increase (D170b)
+7.4%
Peak Reminder-Warning Gap
66,101 accounts
Peak Warning-Disconnection Gap
19,480 accounts
Highest Disconnection Risk Group
$300 - $1,999 arrears
Disconnections Trend
Volatile, but down by 54.8%
Arrears Growth Analysis
To answer the question, “Are arrears (debts) increasing
for residential electricity customers who receive financial assistance
in the form of tailored assistance?”, this section
examines whether financial hardship is escalating among customers
enrolled in tailored assistance programs. The analysis focuses on three
key areas:
Overall Arrears Trend – Are arrears increasing over
time for customers on financial assistance, indicating growing financial
strain?
Arrears Growth by Bracket – Are higher arrears
($2,000+) growing faster than lower arrears (<$1,000)? And does this
indicate debt escalation into higher brackets?
Effectiveness of Assistance by Arrears Bracket –
Are customers’ arrears decreasing over time after entering financial
assistance, or do debts continue to escalate within each bracket?
By evaluating these indicators over time, this analysis aims to
assess whether financial assistance programs are effectively reducing
arrears or if additional consumer protections and support measures are
needed.
1. Overall Arrears Trend Over Time
“Are arrears increasing over time for customers on financial
assistance, indicating growing financial strain?”
Indicator Code
Description
AR031(a)
Residential accounts that started tailored assistance with arrears
below $55 (including credits).
AR031(b)
Residential accounts that started tailored assistance with arrears
between $55 and $999.
AR031(c)
Residential accounts that started tailored assistance with arrears
between $1,000 and $1,999.
AR031(d)
Residential accounts that started tailored assistance with arrears
between $2,000 and $2,999.
AR031(e)
Residential accounts that started tailored assistance with arrears
between $3,000 and $4,999.
AR031(f)
Residential accounts that started tailored assistance with arrears
above $5,000.
Yes and No. YES, high arrears grew while low arrears declined, but
NO, the trends don’t confirm direct debt escalation.
High arrears ($1,000+) grew by 22.5% (from $3,558 to $4,358), but
this increase is moderate and does not indicate widespread debt
escalation.
Low arrears (<$1,000) declined by 14.5% (from $11,684 to $9,993),
meaning fewer customers hold small overdue balances.
Both low and high arrears dipped to lows in mid-2023, then increased
together, which does not align with a direct shift from low to high
arrears.
While some movement into higher arrears is possible, other
factors—such as repayments, financial assistance, or seasonal
fluctuations—may also be influencing these trends.
The overall trend does not show sharp or accelerating growth in high
arrears, suggesting that while financial strain exists, debt escalation
into higher brackets is not a dominant pattern.
3. Assistance Effectiveness by Bracket
“Are customers’ arrears decreasing over time after entering
financial assistance, or do debts continue to escalate within each
bracket?”
Indicator Code
Description
AR031(a)
Residential accounts that started tailored assistance with arrears
below $55 (including credits).
AR031(b)
Residential accounts that started tailored assistance with arrears
between $55 and $999.
AR031(c)
Residential accounts that started tailored assistance with arrears
between $1,000 and $1,999.
AR031(d)
Residential accounts that started tailored assistance with arrears
between $2,000 and $2,999.
AR031(e)
Residential accounts that started tailored assistance with arrears
between $3,000 and $4,999.
AR031(f)
Residential accounts that started tailored assistance with arrears
above $5,000.
### Plot Code
# Define arrears bracket order for visualization
arrears_bracket_levels <- c("Below $55", "$55-$999", "$1,000-$1,999", "$2,000-$2,999", "$3,000-$4,999", "Above $5,000")
# Map arrears categories to readable labels
arrears_data <- customer_data_cleaned %>%
filter(indicator_common_id %in% c("AR031(a)", "AR031(b)", "AR031(c)", "AR031(d)", "AR031(e)", "AR031(f)")) %>%
mutate(arrears_bracket = case_when(
indicator_common_id == "AR031(a)" ~ "Below $55",
indicator_common_id == "AR031(b)" ~ "$55-$999",
indicator_common_id == "AR031(c)" ~ "$1,000-$1,999",
indicator_common_id == "AR031(d)" ~ "$2,000-$2,999",
indicator_common_id == "AR031(e)" ~ "$3,000-$4,999",
indicator_common_id == "AR031(f)" ~ "Above $5,000"
)) %>%
group_by(date, arrears_bracket) %>%
summarise(total_customers = sum(value, na.rm = TRUE), .groups = "drop") %>%
mutate(arrears_bracket = factor(arrears_bracket, levels = arrears_bracket_levels)) # Set factor order
# Define color palette for arrears brackets
arrears_colors <- c("Below $55" = "#a4bdcf", "$55-$999" = "#7a9fbd",
"$1,000-$1,999" = "#4e80a7", "$2,000-$2,999" = "#236092",
"$3,000-$4,999" = "#9467bd", "Above $5,000" = "#cb0456")
# Create stacked area chart
ggplot(arrears_data, aes(x = date, y = total_customers, fill = arrears_bracket)) +
geom_area(alpha = 0.8) +
scale_fill_manual(values = arrears_colors) +
labs(
title = "Shifts in Arrears Brackets Over Time",
x = "Year-Month",
y = "Number of Customers",
fill = "Arrears Bracket"
) +
theme_minimal() +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
### Table Code
# Calculate movement across arrears brackets
table_arrears_movement <- arrears_data %>%
group_by(arrears_bracket) %>%
arrange(date) %>% # Ensure data is ordered correctly before summarization
mutate(
first_date = min(date),
last_date = max(date),
first_value = total_customers[which.min(date)], # Ensure first value is linked to first date
last_value = total_customers[which.max(date)] # Ensure last value is linked to last date
) %>%
summarise(
min_customers = min(total_customers, na.rm = TRUE),
max_customers = max(total_customers, na.rm = TRUE),
total_customers = sum(total_customers, na.rm = TRUE), # Added total column
first_date = first(first_date), # Retain correct first date
first_value = first(first_value), # Ensure first value remains unchanged
last_date = first(last_date), # Retain correct last date
last_value = first(last_value), # Ensure last value remains unchanged
percentage_change = ((last_value - first_value) / first_value) * 100,
.groups = "drop"
) %>%
mutate(
movement_direction = case_when(
percentage_change < 0 ~ "Decreasing (Improvement)",
percentage_change > 0 ~ "Increasing (Escalation)",
TRUE ~ "Stable"
)
)
# Display summary table
print(table_arrears_movement, width = Inf)
Key Insights
No, arrears have not broadly reduced after entering financial
assistance.
The $55-$999 arrears bracket decreased by 19%, indicating that some
customers are reducing their debt after receiving financial
assistance.
All higher arrears brackets ($1,000+) have increased, with the
$1,000-$1,999 group rising by 26.7% and the $5,000+ bracket growing by
30.9%, suggesting that some customers struggle to stabilize their debt
even with assistance.
The overall distribution of arrears remains similar over time,
meaning financial assistance has not drastically shifted customers out
of higher debt brackets.
The number of customers in the lowest arrears category (Below $55)
has increased slightly (+4.15%), but this change is minimal compared to
growth in higher arrears.
As observed earlier, arrears in general have reduced by 5.85%, but
this is because the only bracket that decreased ($55-$999) also has the
highest count of customers. Remove that bracket and arrears have
increased by 15.3%.
Summary of Arrears Insights
“Are arrears (debts) increasing for residential electricity
customers who receive financial assistance in the form of tailored
assistance?”
📌 No, arrears have not broadly increased for residential
electricity customers receiving tailored assistance, but financial
strain persists for many.
Total arrears have declined 5.85%, primarily due to a 19% reduction
in the $55-$999 bracket, which holds the largest number of customers.
However, when excluding this bracket, arrears in all other categories
have increased by 15.3%, indicating that while some customers
successfully reduce their debt, others continue to accumulate more over
time.
The distribution of arrears remains relatively stable, meaning
assistance programs have not significantly shifted customers out of
higher debt brackets. A sharp drop in arrears in mid-2023 stands out as
an anomaly, warranting further investigation into potential economic or
policy-driven factors.
While debt escalation is not widespread, the rising arrears in higher
brackets indicate that financial assistance may not be effectively
supporting all at-risk customers. A targeted review of assistance
programs could help improve their impact on long-term debt
reduction.
Metric
Value
Total Arrears Trend
Volatile, down 5.85%
Low Arrears Change (<$1,000)
-14.5% (Improved)
High Arrears Change ($1,000+)
+22.5% (Increased)
Biggest Arrears Reduction
$55-$999 (-19%)
Biggest Arrears Growth
$5,000+ (+30.9%)
Notable Anomaly
Sharp drop in mid-2023
Payment Assistance Analysis
To answer the question, “Are more residential electricity
customers accessing tailored financial assistance?”, this
section examines trends in assistance uptake and whether customers
successfully complete assistance or struggle to stay enrolled. The
analysis focuses on two key areas:
Overall Financial Assistance Uptake – Are more
residential customers enrolling in tailored financial assistance over
time?
Successful Completion or Struggling to Stay
Enrolled - Is financial assistance helping customers regain
stability, or are many struggling to meet requirements and being removed
from the program?
By evaluating these trends, this analysis determines whether access
to financial assistance is expanding and how effectively customers are
able to stay enrolled and complete the program.
1. Overall Financial Assistance Uptake
“Are more residential customers enrolling in tailored financial
assistance over time?”
Indicator Code
Description
AS022(a)
Residential accounts on tailored assistance that can
pay at least their ongoing usage.
AS022(b)
Residential accounts on tailored assistance that
cannot pay their ongoing usage.
AS031(a)
Residential accounts on tailored assistance with an
electricity concession that can pay at least their
ongoing usage.
AS031(b)
Residential accounts on tailored assistance with an
electricity concession that cannot pay
their ongoing usage.
Yes, more residential customers are enrolling in tailored financial
assistance, but growth has been gradual with fluctuations.
Total enrollment in tailored assistance has increased from 95,863 to
101,959 customers (+6.36%), indicating a steady rise in participation
over time.
Tailored Assistance (Cannot Pay) saw the highest growth (+36.9%),
suggesting a growing number of households unable to meet basic payment
obligations.
Concession Assistance (Can Pay) declined by 25.4%, indicating that
fewer concession recipients who can still afford payments are relying on
support.
Since mid-2022 (it’s lowest point), assistance enrollment has grown
by approximately 15.93%, reinforcing the trend of increasing uptake
after a period of decline.
2. Successful Completion or Struggling to Stay Enrolled
“Is financial assistance helping customers regain stability, or
are many struggling to meet requirements and being removed from the
program?”
Indicator Code
Description
AS061
Residential accounts that exited tailored assistance
with arrears of $0 or a credit balance.
AS080
Residential accounts removed from tailored assistance
due to non-compliance with payment or energy use
requirements.
### Plot Code
# Filter dataset for exit/removal indicators
exit_data <- customer_data_cleaned %>%
filter(indicator_common_id %in% c("AS061", "AS080")) %>%
mutate(exit_type = case_when(
indicator_common_id == "AS061" ~ "Exited with $0 Arrears",
indicator_common_id == "AS080" ~ "Removed for Non-Compliance"
))
# Aggregate total exits by date and type
exit_trend <- exit_data %>%
group_by(date, exit_type) %>%
summarise(total_exits = sum(value, na.rm = TRUE), .groups = "drop")
### Plot 1 - Stacked area chart for exits/removals
ggplot(exit_trend, aes(x = date, y = total_exits, fill = exit_type)) +
geom_area(alpha = 0.8) +
scale_fill_manual(values = c("Exited with $0 Arrears" = "#a4bdcf", "Removed for Non-Compliance" = "#236092")) +
labs(
title = "Customer Movements Out of Financial Assistance",
x = "Year-Month",
y = "Number of Customers",
fill = "Exit Type"
) +
theme_minimal() +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
### Table Code
# Create summary table for exits/removals over time
table_exit_summary <- exit_trend %>%
group_by(exit_type) %>%
summarise(
min_value = min(total_exits, na.rm = TRUE),
max_value = max(total_exits, na.rm = TRUE),
first_date = min(date),
first_value = total_exits[which.min(date)],
last_date = max(date),
last_value = total_exits[which.max(date)],
percentage_change = ((last_value - first_value) / first_value) * 100,
total_count = sum(total_exits, na.rm = TRUE), # Total exits for this type
.groups = "drop"
)
# Calculate total exits across both categories
total_exits_all <- sum(table_exit_summary$total_count, na.rm = TRUE)
# Add % of total exits column
table_exit_summary <- table_exit_summary %>%
mutate(percentage_of_total_exits = (total_count / total_exits_all) * 100)
# Pivot to calculate ratio of successful exits to non-compliant removals
exit_counts <- table_exit_summary %>%
select(exit_type, total_count) %>%
pivot_wider(names_from = exit_type, values_from = total_count)
# Add ratio column
table_exit_summary <- table_exit_summary %>%
mutate(ratio_success_to_noncompliant = exit_counts$`Exited with $0 Arrears` / exit_counts$`Removed for Non-Compliance`)
# Display summary tables
print(table_exit_summary, width = Inf)
Key Insights
No, more customers are struggling to stay enrolled in financial
assistance than successfully exiting with $0 arrears.
The high rate of non-compliance exits (65.4%) vs. successful
completions (34.6%) demonstrates that more customers fail to meet
requirements than successfully repay debts.
The 38.7% decline in successful completions suggests it is becoming
harder for participants to fully resolve their arrears.
The 5.5% rise in non-compliance removals highlights that financial
hardship persists for many enrolled customers.
The low success-to-noncompliance ratio (0.53) reinforces that for
every customer who exits debt-free, nearly two are removed, showing that
the program struggles to retain participants effectively.
Summary of Assistance Insights
“Are more residential electricity customers accessing tailored
financial assistance?”
📌 Yes, but participation trends show mixed signals, with enrollment
increasing overall while program exits due to non-compliance remain
high.
Financial assistance participation has increased by 6.36% overall and
15.93% since mid-2022, reflecting rising demand. However, growth is
uneven—assistance for those who cannot pay without a concession surged
36.9%, while participation among concession recipients who can pay fell
25.4%, suggesting worsening financial strain among the most
vulnerable.
Despite increased enrollment, program retention is a challenge. 65.4%
of exits are due to non-compliance, while just 34.6% exit successfully
with $0 arrears. The success-to-noncompliance ratio (0.53) indicates
that for every successful completion, nearly two customers are removed
due to non-compliance. Additionally, successful completions have dropped
by 38.7%, signaling greater difficulty in regaining financial stability.
These trends highlight the need to assess whether current assistance
structures are effectively supporting long-term recovery.
Metric
Value
Total Assistance Enrollment Growth
+6.36%
Growth Since Mid-2022 Low
+15.93%
Largest Assistance Uptake
Cannot Pay (No Concession) +36.9%
Largest Assistance Decline
Can Pay (With Concession) -25.4%
Non-Compliance Exits
65.4% of all exits
Successful Completions
34.6% of all exits
Conclusion
“Is there evidence that cost-of-living pressures are driving
financial hardship among residential electricity customers?”
📌 Yes, cost-of-living pressures are contributing to
financial hardship among residential electricity customers, as reflected
in rising financial assistance enrollment, persistent arrears for some,
and increasing non-compliance exits.
This analysis set out to answer three key questions:
Are more customers at risk of disconnection?
Are arrears increasing among those receiving financial
assistance?
And is tailored financial assistance enrollment growing while
effectively supporting customers?
Disconnection risk has risen, with a 7.4% surge in warning notices,
signaling more households struggling to pay on time. However, actual
disconnections remain low, suggesting many customers resolve overdue
balances before service termination.
Arrears trends show financial hardship remains a significant
challenge for many, with high arrears ($1,000+) increasing by 22.5%,
while overall arrears have fluctuated but not shown a sustained upward
trend.
Most notably, financial assistance enrollment has increased by 6.36%
overall and 15.93% since mid-2022. However, 65.4% of exits are due to
non-compliance, suggesting that many customers either struggle to meet
assistance program requirements or disengage from structured repayment
plans.
These findings highlight growing financial strain among residential
electricity customers, reinforcing the need to assess whether existing
support measures are effectively helping those most at risk.
1️⃣ 7.4% increase in disconnection warning
notices.
2️⃣ 22.5% increase in high arrears ($1,000+) (Debt
persistence despite assistance)
3️⃣ 15.93% growth in assistance uptake since mid-2022
low (More people seeking help)
4️⃣ 65.4% of exits due to non-compliance (Many
struggling to sustain assistance)