2025 Federal Election: Elector Trends by Age and Gender

Diya Anna Oommen (s4078794)

2025-06-08

Dataset overview and loading

  • 🗳️ Source: Australian Electoral Commission (AEC).

  • 👥 Content: Elector counts by:Age group,Gender,Electoral division.

  • 🔍 Purpose: Understand demographic trends in voter enrolment ahead of the 2025 Federal Election.

## Warning: package 'tidyverse' was built under R version 4.4.3
## Warning: package 'ggplot2' was built under R version 4.4.3
## Warning: package 'tidyr' was built under R version 4.4.3
## Warning: package 'purrr' was built under R version 4.4.3
## Warning: package 'forcats' was built under R version 4.4.3
## Warning: package 'lubridate' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
## New names:
## Rows: 625 Columns: 17
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (14): Federal Entitlement, Fed/State & Fed only, ...3, ...4, ...5, ...6,...
## lgl  (3): ...15, ...16, ...17
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## Rows: 625
## Columns: 17
## $ `Federal Entitlement`  <chr> "Indeterminate/Unknown includes enrolments for …
## $ `Fed/State & Fed only` <chr> NA, NA, NA, NA, NA, NA, "18-19", "164,010", "3,…
## $ ...3                   <chr> NA, NA, NA, NA, NA, NA, "20-24", "417,467", "9,…
## $ ...4                   <chr> NA, NA, NA, NA, NA, NA, "25-29", "421,163", "8,…
## $ ...5                   <chr> NA, NA, NA, NA, NA, NA, "30-34", "445,490", "8,…
## $ ...6                   <chr> NA, NA, NA, NA, NA, NA, "35-39", "479,932", "9,…
## $ ...7                   <chr> NA, NA, NA, NA, NA, NA, "40-44", "494,588", "9,…
## $ ...8                   <chr> NA, NA, NA, NA, NA, NA, "45-49", "454,793", "9,…
## $ ...9                   <chr> NA, NA, NA, NA, NA, NA, "50-54", "477,151", "10…
## $ ...10                  <chr> NA, NA, NA, NA, NA, NA, "55-59", "435,210", "9,…
## $ ...11                  <chr> NA, NA, NA, NA, NA, NA, "60-64", "448,514", "9,…
## $ ...12                  <chr> NA, NA, NA, NA, NA, NA, "65-69", "411,165", "8,…
## $ ...13                  <chr> NA, NA, NA, NA, NA, NA, "70+", "1,045,506", "21…
## $ ...14                  <chr> NA, NA, NA, NA, NA, NA, "TOTAL", "5,694,989", "…
## $ ...15                  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ ...16                  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ ...17                  <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## New names:
## Rows: 619 Columns: 17
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (14): ...1, ...2, ...3, ...4, ...5, ...6, ...7, ...8, ...9, ...10, ...11... lgl
## (3): ...15, ...16, ...17
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
## • `` -> `...2`
## • `` -> `...3`
## • `` -> `...4`
## • `` -> `...5`
## • `` -> `...6`
## • `` -> `...7`
## • `` -> `...8`
## • `` -> `...9`
## • `` -> `...10`
## • `` -> `...11`
## • `` -> `...12`
## • `` -> `...13`
## • `` -> `...14`
## • `` -> `...15`
## • `` -> `...16`
## • `` -> `...17`
## Rows: 619
## Columns: 17
## $ ...1  <chr> NA, "NSW", "BANKS", "Female", "Male", "Indeterminate/Unknown", "…
## $ ...2  <chr> "18-19", "164,010", "3,500", "1,702", "1,790", "8", "3,046", "1,…
## $ ...3  <chr> "20-24", "417,467", "9,486", "4,647", "4,823", "16", "8,641", "4…
## $ ...4  <chr> "25-29", "421,163", "8,738", "4,279", "4,453", "6", "9,544", "4,…
## $ ...5  <chr> "30-34", "445,490", "8,806", "4,329", "4,467", "10", "9,922", "4…
## $ ...6  <chr> "35-39", "479,932", "9,378", "4,750", "4,613", "15", "10,702", "…
## $ ...7  <chr> "40-44", "494,588", "9,883", "5,032", "4,845", "6", "10,783", "5…
## $ ...8  <chr> "45-49", "454,793", "9,509", "4,941", "4,560", "8", "9,880", "4,…
## $ ...9  <chr> "50-54", "477,151", "10,079", "5,249", "4,827", "3", "10,392", "…
## $ ...10 <chr> "55-59", "435,210", "9,759", "5,082", "4,676", "1", "9,522", "4,…
## $ ...11 <chr> "60-64", "448,514", "9,893", "5,024", "4,866", "3", "9,401", "4,…
## $ ...12 <chr> "65-69", "411,165", "8,545", "4,376", "4,168", "1", "7,981", "4,…
## $ ...13 <chr> "70+", "1,045,506", "21,809", "11,889", "9,920", "-", "21,011", …
## $ ...14 <chr> "TOTAL", "5,694,989", "119,385", "61,300", "58,008", "77", "120,…
## $ ...15 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ ...16 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ ...17 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, …

Preprocessing(data cleaning)

  • 🧾 Raw Input: Original dataset included metadata and non-standard headers

  • 🛠️ Processing: Cleaned and transformed:Set proper column names,Converted to appropriate data types

  • 🔍 Ready for Analysis: We can now explore trends by age, gender, and region

## Rows: 618
## Columns: 14
## $ NA      <chr> "NSW", "BANKS", "Female", "Male", "Indeterminate/Unknown", "BA…
## $ `18-19` <chr> "164,010", "3,500", "1,702", "1,790", "8", "3,046", "1,444", "…
## $ `20-24` <chr> "417,467", "9,486", "4,647", "4,823", "16", "8,641", "4,182", …
## $ `25-29` <chr> "421,163", "8,738", "4,279", "4,453", "6", "9,544", "4,627", "…
## $ `30-34` <chr> "445,490", "8,806", "4,329", "4,467", "10", "9,922", "4,827", …
## $ `35-39` <chr> "479,932", "9,378", "4,750", "4,613", "15", "10,702", "5,321",…
## $ `40-44` <chr> "494,588", "9,883", "5,032", "4,845", "6", "10,783", "5,418", …
## $ `45-49` <chr> "454,793", "9,509", "4,941", "4,560", "8", "9,880", "4,966", "…
## $ `50-54` <chr> "477,151", "10,079", "5,249", "4,827", "3", "10,392", "5,308",…
## $ `55-59` <chr> "435,210", "9,759", "5,082", "4,676", "1", "9,522", "4,922", "…
## $ `60-64` <chr> "448,514", "9,893", "5,024", "4,866", "3", "9,401", "4,755", "…
## $ `65-69` <chr> "411,165", "8,545", "4,376", "4,168", "1", "7,981", "4,154", "…
## $ `70+`   <chr> "1,045,506", "21,809", "11,889", "9,920", "-", "21,011", "11,3…
## $ TOTAL   <chr> "5,694,989", "119,385", "61,300", "58,008", "77", "120,825", "…
## Warning: There were 8 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `across(-Category, ~as.numeric(gsub(",", "", .)))`.
## Caused by warning:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 7 remaining warnings.
## Rows: 618
## Columns: 14
## $ Category <chr> "NSW", "BANKS", "Female", "Male", "Indeterminate/Unknown", "B…
## $ `18-19`  <dbl> 164010, 3500, 1702, 1790, 8, 3046, 1444, 1593, 9, 3508, 1719,…
## $ `20-24`  <dbl> 417467, 9486, 4647, 4823, 16, 8641, 4182, 4440, 19, 9131, 442…
## $ `25-29`  <dbl> 421163, 8738, 4279, 4453, 6, 9544, 4627, 4891, 26, 9698, 4638…
## $ `30-34`  <dbl> 445490, 8806, 4329, 4467, 10, 9922, 4827, 5078, 17, 10253, 50…
## $ `35-39`  <dbl> 479932, 9378, 4750, 4613, 15, 10702, 5321, 5365, 16, 11355, 5…
## $ `40-44`  <dbl> 494588, 9883, 5032, 4845, 6, 10783, 5418, 5352, 13, 12020, 60…
## $ `45-49`  <dbl> 454793, 9509, 4941, 4560, 8, 9880, 4966, 4907, 7, 10869, 5473…
## $ `50-54`  <dbl> 477151, 10079, 5249, 4827, 3, 10392, 5308, 5080, 4, 10679, 55…
## $ `55-59`  <dbl> 435210, 9759, 5082, 4676, 1, 9522, 4922, 4596, 4, 9550, 4990,…
## $ `60-64`  <dbl> 448514, 9893, 5024, 4866, 3, 9401, 4755, 4642, 4, 9325, 4782,…
## $ `65-69`  <dbl> 411165, 8545, 4376, 4168, 1, 7981, 4154, 3825, 2, 8194, 4308,…
## $ `70+`    <dbl> 1045506, 21809, 11889, 9920, NA, 21011, 11351, 9657, 3, 21404…
## $ TOTAL    <dbl> 5694989, 119385, 61300, 58008, 77, 120825, 61275, 59426, 124,…
## Rows: 609
## Columns: 14
## $ Category <chr> "NSW", "BANKS", "Female", "Male", "Indeterminate/Unknown", "B…
## $ `18-19`  <dbl> 164010, 3500, 1702, 1790, 8, 3046, 1444, 1593, 9, 3508, 1719,…
## $ `20-24`  <dbl> 417467, 9486, 4647, 4823, 16, 8641, 4182, 4440, 19, 9131, 442…
## $ `25-29`  <dbl> 421163, 8738, 4279, 4453, 6, 9544, 4627, 4891, 26, 9698, 4638…
## $ `30-34`  <dbl> 445490, 8806, 4329, 4467, 10, 9922, 4827, 5078, 17, 10253, 50…
## $ `35-39`  <dbl> 479932, 9378, 4750, 4613, 15, 10702, 5321, 5365, 16, 11355, 5…
## $ `40-44`  <dbl> 494588, 9883, 5032, 4845, 6, 10783, 5418, 5352, 13, 12020, 60…
## $ `45-49`  <dbl> 454793, 9509, 4941, 4560, 8, 9880, 4966, 4907, 7, 10869, 5473…
## $ `50-54`  <dbl> 477151, 10079, 5249, 4827, 3, 10392, 5308, 5080, 4, 10679, 55…
## $ `55-59`  <dbl> 435210, 9759, 5082, 4676, 1, 9522, 4922, 4596, 4, 9550, 4990,…
## $ `60-64`  <dbl> 448514, 9893, 5024, 4866, 3, 9401, 4755, 4642, 4, 9325, 4782,…
## $ `65-69`  <dbl> 411165, 8545, 4376, 4168, 1, 7981, 4154, 3825, 2, 8194, 4308,…
## $ `70+`    <dbl> 1045506, 21809, 11889, 9920, NA, 21011, 11351, 9657, 3, 21404…
## $ TOTAL    <dbl> 5694989, 119385, 61300, 58008, 77, 120825, 61275, 59426, 124,…
##    Category             18-19            20-24             25-29        
##  Length:609         Min.   :     2   Min.   :      7   Min.   :      4  
##  Class :character   1st Qu.:   890   1st Qu.:   2643   1st Qu.:   2665  
##  Mode  :character   Median :  1674   Median :   4489   Median :   4562  
##                     Mean   :  3239   Mean   :   8792   Mean   :   9007  
##                     3rd Qu.:  2320   3rd Qu.:   6513   3rd Qu.:   7131  
##                     Max.   :493201   Max.   :1338599   Max.   :1371382  
##      30-34             35-39             40-44             45-49        
##  Min.   :      3   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:   2922   1st Qu.:   2911   1st Qu.:   2876   1st Qu.:   2710  
##  Median :   4852   Median :   5114   Median :   5324   Median :   4896  
##  Mean   :   9573   Mean   :  10241   Mean   :  10414   Mean   :   9513  
##  3rd Qu.:   7052   3rd Qu.:   7946   3rd Qu.:   8085   3rd Qu.:   7232  
##  Max.   :1457543   Max.   :1559172   Max.   :1585566   Max.   :1448306  
##      50-54             55-59             60-64             65-69        
##  Min.   :      0   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:   3209   1st Qu.:   2972   1st Qu.:   2815   1st Qu.:   2136  
##  Median :   5135   Median :   4763   Median :   4733   Median :   4240  
##  Mean   :   9978   Mean   :   9220   Mean   :   9244   Mean   :   8443  
##  3rd Qu.:   7188   3rd Qu.:   7027   3rd Qu.:   6683   3rd Qu.:   6329  
##  Max.   :1519178   Max.   :1403810   Max.   :1407365   Max.   :1285490  
##       70+              TOTAL         
##  Min.   :      0   Min.   :      46  
##  1st Qu.:   4169   1st Qu.:   38491  
##  Median :  10639   Median :   60587  
##  Mean   :  21210   Mean   :  118876  
##  3rd Qu.:  15480   3rd Qu.:   88962  
##  Max.   :3229185   Max.   :18098797
##    Category             18-19            20-24             25-29        
##  Length:453         Min.   :     2   Min.   :      7   Min.   :      4  
##  Class :character   1st Qu.:    20   1st Qu.:     38   1st Qu.:     25  
##  Mode  :character   Median :  1444   Median :   4087   Median :   4008  
##                     Mean   :  2190   Mean   :   5941   Mean   :   6088  
##                     3rd Qu.:  1761   3rd Qu.:   4630   3rd Qu.:   4805  
##                     Max.   :493201   Max.   :1338599   Max.   :1371382  
##      30-34             35-39             40-44             45-49        
##  Min.   :      3   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:     18   1st Qu.:     12   1st Qu.:      9   1st Qu.:      7  
##  Median :   4218   Median :   4518   Median :   4769   Median :   4506  
##  Mean   :   6474   Mean   :   6925   Mean   :   7041   Mean   :   6434  
##  3rd Qu.:   5088   3rd Qu.:   5383   3rd Qu.:   5508   3rd Qu.:   5032  
##  Max.   :1457543   Max.   :1559172   Max.   :1585566   Max.   :1448306  
##      50-54             55-59             60-64             65-69        
##  Min.   :      0   Min.   :      0   Min.   :      0   Min.   :      0  
##  1st Qu.:      7   1st Qu.:      5   1st Qu.:      5   1st Qu.:      4  
##  Median :   4803   Median :   4367   Median :   4125   Median :   3622  
##  Mean   :   6752   Mean   :   6244   Mean   :   6264   Mean   :   5723  
##  3rd Qu.:   5259   3rd Qu.:   4917   3rd Qu.:   4981   3rd Qu.:   4521  
##  Max.   :1519178   Max.   :1403810   Max.   :1407365   Max.   :1285490  
##       70+              TOTAL         
##  Min.   :      0   Min.   :      46  
##  1st Qu.:      4   1st Qu.:     144  
##  Median :   8431   Median :   58257  
##  Mean   :  14367   Mean   :   80444  
##  3rd Qu.:  11889   3rd Qu.:   61944  
##  Max.   :3229185   Max.   :18098797
## # A tibble: 6 × 14
##   Category       `18-19` `20-24` `25-29` `30-34` `35-39` `40-44` `45-49` `50-54`
##   <chr>            <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1 Female            1702    4647    4279    4329    4750    5032    4941    5249
## 2 Male              1790    4823    4453    4467    4613    4845    4560    4827
## 3 Indeterminate…       8      16       6      10      15       6       8       3
## 4 Female            1444    4182    4627    4827    5321    5418    4966    5308
## 5 Male              1593    4440    4891    5078    5365    5352    4907    5080
## 6 Indeterminate…       9      19      26      17      16      13       7       4
## # ℹ 5 more variables: `55-59` <dbl>, `60-64` <dbl>, `65-69` <dbl>, `70+` <dbl>,
## #   TOTAL <dbl>
##  [1] "Category" "18-19"    "20-24"    "25-29"    "30-34"    "35-39"   
##  [7] "40-44"    "45-49"    "50-54"    "55-59"    "60-64"    "65-69"   
## [13] "70+"      "TOTAL"
## Rows: 453
## Columns: 14
## $ Category <chr> "Female", "Male", "Indeterminate/Unknown", "Female", "Male", …
## $ `18-19`  <dbl> 1702, 1790, 8, 1444, 1593, 9, 1719, 1776, 13, 2198, 2320, 20,…
## $ `20-24`  <dbl> 4647, 4823, 16, 4182, 4440, 19, 4422, 4682, 27, 5091, 5474, 2…
## $ `25-29`  <dbl> 4279, 4453, 6, 4627, 4891, 26, 4638, 5045, 15, 3656, 4391, 20…
## $ `30-34`  <dbl> 4329, 4467, 10, 4827, 5078, 17, 5016, 5221, 16, 3446, 3691, 1…
## $ `35-39`  <dbl> 4750, 4613, 15, 5321, 5365, 16, 5708, 5639, 8, 4666, 4298, 6,…
## $ `40-44`  <dbl> 5032, 4845, 6, 5418, 5352, 13, 6056, 5957, 7, 6223, 5853, 7, …
## $ `45-49`  <dbl> 4941, 4560, 8, 4966, 4907, 7, 5473, 5391, 5, 6282, 6101, 1, 4…
## $ `50-54`  <dbl> 5249, 4827, 3, 5308, 5080, 4, 5557, 5116, 6, 6353, 6132, 5, 4…
## $ `55-59`  <dbl> 5082, 4676, 1, 4922, 4596, 4, 4990, 4558, 2, 5510, 5125, 3, 4…
## $ `60-64`  <dbl> 5024, 4866, 3, 4755, 4642, 4, 4782, 4540, 3, 5285, 5244, 4, 4…
## $ `65-69`  <dbl> 4376, 4168, 1, 4154, 3825, 2, 4308, 3883, 3, 4610, 4349, 2, 3…
## $ `70+`    <dbl> 11889, 9920, 0, 11351, 9657, 3, 11816, 9581, 7, 13301, 11220,…
## $ TOTAL    <dbl> 61300, 58008, 77, 61275, 59426, 124, 64485, 61389, 112, 66621…

Slide with Plot

##Total electors by gender

  • 🌏 Displays national-level gender distribution of enrolled electors across all age groups.
  • ⚖️ Male and female elector counts are closely matched, showing minimal gender disparity in enrolment.
  • 🧩 “Indeterminate” gender category has negligible representation, with limited impact on overall trends.

Age Group Distribution by Gender

  • 👥 Elector numbers peak in the 30–64 age range, highlighting the core voting demographic.
  • ⚖️ Gender distribution remains balanced across all age groups, with no major disparities observed.
  • 🌱👵 Lowest elector counts appear in the youngest (18–24) and oldest (70+) groups, indicating areas with lower engagement or population.

Stacked Bar Chart: Multiple Categories per Age Group

  • 🧱 Stacks elector counts by category within each age group, enabling side-by-side comparison of group contributions.
  • 🧭 Highlights how divisions or genders vary across age groups, revealing hidden patterns in voter distribution.
  • 🌈 Exposes clear contrasts between categories, especially in middle-aged and older groups, enhancing decision-making insight.

Proportional Stacked Bar Chart (Gender % in Age Group)

  • 📊 Transforms raw counts into proportions, allowing for direct comparison across age groups.
  • ⚖️ Clearly visualises gender balance within each age bracket, making disparities easy to spot.
  • 🔄 Shows that gender distribution remains relatively stable across most age ranges — indicating demographic consistency.

Heatmap: Age vs Category

  • 🎨 Color intensity reveals elector concentration — darker shades represent higher enrolment.
  • 👀 Instantly highlights patterns, making it easy to spot regions or age groups with unusually high or low voter counts.
  • 🧓 Middle-aged groups (especially 40–59) show the deepest color tones, confirming they form the electoral majority.

🔍 Discussion & Key Insights

  • 🧓 Elector age trends: The largest voter group falls within the 40–64 age range — indicating a middle-aged voter majority.
  • ⚖️ Gender balance: Overall, male and female elector counts are balanced across most regions.
  • 🧹 Data quality: Minor data issues (e.g., ‘NA’, ‘-’) were cleaned to ensure accurate visual analysis.
  • 🗺️ Regional variation: Heatmap visuals revealed that certain states have younger or older leaning age brackets, which may impact campaign strategies.

➡️ These insights help decode where the voter power lies — both demographically and geographically.

##Conclusion & Reflection

  • ✅ The 2025 electorate shows a strong demographic balance between genders.
  • 📊 The majority of voters are aged 30–59, a key group for political engagement.
  • 📍 Interactive visualisation tools like heatmaps and bar charts were effective in locating voter density hotspots.
  • 🔧 These findings can support campaign resource planning, outreach strategy, and awareness efforts leading up to the election.

🎯 Overall, data storytelling enabled us to uncover patterns that raw numbers alone wouldn’t reveal.

References

Australian Electoral Commission. (2025). Elector count by age and gender. Retrieved from https://www.aec.gov.au/ - R Packages: tidyverse, ggplot2, readr, janitor,‘revealjs’ - Hosted and compiled using Posit Cloud