# ---------- Helper functions ----------

# Check that a file exists before reading it.
check_file <- function(path) {
  if (!file.exists(path)) {
    stop(
      paste0(
        "Missing file: ", path, "\n",
        "Place the required cleaned data file inside the data/ folder, ",
        "then knit the RMarkdown file again."
      )
    )
  }
}

# A clean publication-style theme.
theme_story <- function(base_size = 12) {
  theme_minimal(base_size = base_size) +
    theme(
      plot.title = element_text(face = "bold", size = 15),
      plot.subtitle = element_text(size = 11, colour = "grey30"),
      plot.caption = element_text(size = 8, colour = "grey40", hjust = 0),
      axis.title = element_text(face = "bold"),
      panel.grid.minor = element_blank(),
      legend.title = element_text(face = "bold"),
      legend.position = "bottom"
    )
}

# Use a simple accessible palette.
story_palette <- c(
  "#00467F", "#D55E00", "#009E73", "#CC79A7",
  "#F0E442", "#56B4E9", "#999999", "#E69F00"
)

# Convert ggplot to plotly with consistent sizing.
make_interactive <- function(plot_object) {
  ggplotly(plot_object, tooltip = "text", width = 600) %>%
    layout(
      hoverlabel = list(align = "left"),
      legend = list(orientation = "h", x = 0, y = -0.2)
    ) %>%
    config(displaylogo = FALSE)
}

Story pitch

Artificial intelligence is no longer a distant future issue for Australian students. It is already reshaping how people study, how employers recruit, and what skills graduates are expected to bring into the workplace. Australian business data shows strong growth in AI-related research and development, while labour-market vacancy data can reveal whether demand is shifting towards digital and AI-adjacent occupations.

But the key question is not simply whether Australia is adopting AI. The more human question is whether students are being prepared quickly enough. If higher education enrolments and completions are not aligned with emerging labour demand, students may graduate with qualifications that are valuable, but not fully matched to the skills employers increasingly expect.

This five-chart visual story uses open Australian data to connect three parts of the same issue: AI investment, job-market demand, and the higher education student pipeline. It begins with the rise of AI research investment, then moves to occupation-level vacancy trends. It then examines whether students are entering and completing courses in fields most connected to digital and AI-shaped work. The final chart shows that AI readiness is not only about individual motivation, but also about field of study, geography, and access to relevant opportunities.

Data preparation

Required cleaned files

Before knitting the final report, create a folder called data in the same folder as this .Rmd file.

The template expects these cleaned CSV files:

  1. data/abs_ai_rd_clean.csv
    Required columns: indicator, year, value_million

  2. data/ivi_monthly_clean.csv
    Required columns: month, year, state, occupation_group, vacancies

  3. data/higher_ed_enrolments_clean.csv
    Required columns: year, field_of_education, enrolments

  4. data/higher_ed_completions_clean.csv
    Required columns: year, field_of_education, completions

# ---------- Load cleaned ABS AI R&D data ----------
check_file("data/abs_ai_rd_clean.csv")

abs_ai_rd <- read_csv("data/abs_ai_rd_clean.csv") %>%
  clean_names() %>%
  mutate(value_million = as.numeric(value_million)) %>%
  group_by(indicator) %>%
  arrange(year, .by_group = TRUE) %>%
  mutate(index_2021_22 = value_million / first(value_million) * 100) %>%
  ungroup()

# ---------- Load cleaned IVI data ----------
check_file("data/ivi_monthly_clean.csv")

ivi <- read_csv("data/ivi_monthly_clean.csv") %>%
  clean_names() %>%
  mutate(
    month = as.Date(month),
    year = as.integer(year),
    state = as.factor(state),
    occupation_group = as.factor(occupation_group),
    vacancies = as.numeric(vacancies)
  )

# ---------- Load cleaned higher education enrolment data ----------
check_file("data/higher_ed_enrolments_clean.csv")

higher_ed_enrolments <- read_csv("data/higher_ed_enrolments_clean.csv") %>%
  clean_names() %>%
  mutate(
    year = as.integer(year),
    field_of_education = as.factor(field_of_education),
    enrolments = as.numeric(enrolments)
  )

# ---------- Load cleaned higher education completion data ----------
check_file("data/higher_ed_completions_clean.csv")

higher_ed_completions <- read_csv("data/higher_ed_completions_clean.csv") %>%
  clean_names() %>%
  mutate(
    year = as.integer(year),
    field_of_education = as.factor(field_of_education),
    completions = as.numeric(completions)
  )
# Fields and occupations used as AI/digital-adjacent indicators.
# Edit these names after checking the exact labels in your cleaned data.

digital_occupations <- c(
  "Health, Education, ICT and Other Managers",
  "ICT Professionals",
  "Information Professionals",
  "Business, Finance and Human Resource Professionals",
  "Engineering, ICT and Science Technicians",
  "Engineers",
  "Science Professionals and Veterinarians"
)

future_facing_fields <- c(
  "Information Technology",
  "Engineering and Related Technologies",
  "Management and Commerce",
  "Natural and Physical Sciences",
  "Creative Arts",
  "Society and Culture"
)

Chart 1: AI R&D is accelerating

chart1_data <- abs_ai_rd %>%
  mutate(
    label = paste0(
      indicator, "<br>",
      "Year: ", year, "<br>",
      "Value: $", comma(value_million), " million<br>",
      "Index: ", round(index_2021_22, 1), " where 2021-22 = 100"
    )
  )

p1 <- ggplot(
  chart1_data,
  aes(
    x = year,
    y = index_2021_22,
    group = indicator,
    colour = indicator,
    text = label
  )
) +
  geom_line(linewidth = 1.2) +
  geom_point(size = 3) +
  scale_colour_manual(values = story_palette) +
  scale_y_continuous(labels = comma) +
  labs(
    title = "AI R&D is growing much faster than total business R&D",
    subtitle = "Indexed change from 2021-22 to 2023-24, where 2021-22 equals 100.",
    x = NULL,
    y = "Index, 2021-22 = 100",
    colour = NULL,
    caption = "Source: Australian Bureau of Statistics, Research and Experimental Development, Businesses, Australia, 2023-24."
  ) +
  theme_story()

make_interactive(p1)

Narrative note:
AI is not only a classroom issue. Australian firms are already investing heavily in AI. The first chart shows that AI-related R&D has accelerated much faster than total business R&D.

Chart 2: Digital job demand is still elevated

chart2_data <- ivi %>%
  filter(occupation_group %in% digital_occupations) %>%
  group_by(year, occupation_group) %>%
  summarise(vacancies = sum(vacancies, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    label = paste0(
      "Occupation group: ", occupation_group, "<br>",
      "Year: ", year, "<br>",
      "Online job ads: ", comma(round(vacancies))
    )
  )

p2 <- ggplot(
  chart2_data,
  aes(
    x = year,
    y = vacancies,
    colour = occupation_group,
    group = occupation_group,
    text = label
  )
) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  scale_colour_manual(values = story_palette) +
  scale_y_continuous(labels = comma) +
  labs(
    title = "Digital and AI-adjacent occupations are competing for attention",
    subtitle = "Annual online job advertisements by selected occupation groups.",
    x = NULL,
    y = "Online job advertisements",
    colour = "Occupation group",
    caption = "Source: Jobs and Skills Australia, Internet Vacancy Index."
  ) +
  theme_story()

make_interactive(p2)

Narrative note:
This chart moves from business investment to the labour market. If AI changes work, students will feel it first through changing job advertisements and graduate expectations.

Chart 3: Students are not evenly distributed across future-facing fields

chart3_data <- higher_ed_enrolments %>%
  filter(field_of_education %in% future_facing_fields) %>%
  group_by(year, field_of_education) %>%
  summarise(enrolments = sum(enrolments, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    label = paste0(
      "Field: ", field_of_education, "<br>",
      "Year: ", year, "<br>",
      "Enrolments: ", comma(round(enrolments))
    )
  )

p3 <- ggplot(
  chart3_data,
  aes(
    x = year,
    y = enrolments,
    fill = field_of_education,
    text = label
  )
) +
  geom_col(position = "stack") +
  scale_fill_manual(values = story_palette) +
  scale_y_continuous(labels = comma) +
  labs(
    title = "The student pipeline is spread unevenly across future-facing fields",
    subtitle = "Higher education enrolments by selected field of education.",
    x = NULL,
    y = "Student enrolments",
    fill = "Field of education",
    caption = "Source: Australian Government Department of Education, Higher Education Student Data."
  ) +
  theme_story()

make_interactive(p3)

Narrative note:
Student readiness is not only about whether students use AI tools. It also depends on whether enough students are gaining technical, analytical, and cross-disciplinary skills through their courses.

Chart 4: Demand and completions are moving at different speeds

demand_index <- ivi %>%
  filter(occupation_group %in% digital_occupations) %>%
  group_by(year) %>%
  summarise(value = sum(vacancies, na.rm = TRUE), .groups = "drop") %>%
  arrange(year) %>%
  mutate(
    series = "Digital and AI-adjacent job ads",
    index = value / first(value) * 100
  )

completion_index <- higher_ed_completions %>%
  filter(field_of_education %in% c("Information Technology", "Engineering and Related Technologies", "Natural and Physical Sciences")) %>%
  group_by(year) %>%
  summarise(value = sum(completions, na.rm = TRUE), .groups = "drop") %>%
  arrange(year) %>%
  mutate(
    series = "AI-relevant course completions",
    index = value / first(value) * 100
  )

common_years <- intersect(demand_index$year, completion_index$year)
base_year <- min(common_years)

chart4_data <- bind_rows(demand_index, completion_index) %>%
  filter(year %in% common_years) %>%
  group_by(series) %>%
  arrange(year, .by_group = TRUE) %>%
  mutate(index = value / value[year == base_year][1] * 100) %>%
  ungroup() %>%
  mutate(
    label = paste0(
      series, "<br>",
      "Year: ", year, "<br>",
      "Index: ", round(index, 1), " where ", base_year, " = 100<br>",
      "Raw value: ", comma(round(value))
    )
  )

p4 <- ggplot(
  chart4_data,
  aes(
    x = year,
    y = index,
    colour = series,
    group = series,
    text = label
  )
) +
  geom_hline(yintercept = 100, linetype = "dashed", colour = "grey60") +
  geom_line(linewidth = 1.2) +
  geom_point(size = 2.8) +
  scale_colour_manual(values = story_palette) +
  scale_y_continuous(labels = comma) +
  labs(
    title = "Are course completions keeping pace with labour-market demand?",
    subtitle = "Indexed comparison using the first common year as 100.",
    x = NULL,
    y = "Index",
    colour = NULL,
    caption = "Sources: Jobs and Skills Australia IVI; Australian Government Department of Education Higher Education Student Data."
  ) +
  theme_story()

make_interactive(p4)

Narrative note:
This is the central comparison. If job demand rises faster than completions in AI-relevant fields, students may face a preparation gap.

Chart 5: AI readiness also depends on geography

latest_year <- max(ivi$year, na.rm = TRUE)

chart5_data <- ivi %>%
  filter(
    year == latest_year,
    occupation_group %in% digital_occupations
  ) %>%
  group_by(state, occupation_group) %>%
  summarise(vacancies = sum(vacancies, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    label = paste0(
      "State/territory: ", state, "<br>",
      "Occupation group: ", occupation_group, "<br>",
      "Year: ", latest_year, "<br>",
      "Online job ads: ", comma(round(vacancies))
    )
  )

p5 <- ggplot(
  chart5_data,
  aes(
    x = state,
    y = fct_reorder(occupation_group, vacancies, .fun = sum),
    fill = vacancies,
    text = label
  )
) +
  geom_tile(colour = "white", linewidth = 0.4) +
  scale_fill_viridis_c(option = "C", labels = comma) +
  labs(
    title = "AI readiness is uneven across place and occupation",
    subtitle = paste0("Online job advertisements by state and selected occupation group, ", latest_year, "."),
    x = NULL,
    y = NULL,
    fill = "Job ads",
    caption = "Source: Jobs and Skills Australia, Internet Vacancy Index."
  ) +
  theme_story() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

make_interactive(p5)

Narrative note:
The final chart shows that AI readiness is not only a national issue. Students in different fields and states may face different opportunity landscapes.

Summary for the editor

AI is already moving through business investment, labour demand, and higher education. These charts suggest that students need more than casual familiarity with generative AI tools. They need structured opportunities to develop digital literacy, data confidence, domain knowledge, and human judgement. The risk is not simply that AI will replace graduates. The risk is that students who are not prepared to work with AI may be left behind by those who are.

References

Australian Bureau of Statistics. (2025). AI now fastest growing area for business R&D. Australian Bureau of Statistics.

Australian Bureau of Statistics. (2025). Research and Experimental Development, Businesses, Australia, 2023-24 financial year. Australian Bureau of Statistics.

Australian Government Department of Education. (2026). Higher Education Student Data. Department of Education.

Jobs and Skills Australia. (2026). Internet Vacancy Index. Australian Government.

Acknowledgements

I used ChatGPT to assist with planning the story structure, identifying possible open data sources, refining chart ideas, and improving wording for the story pitch. All data selection, interpretation, R code checking, visualisation design decisions, and final submission content were reviewed and edited by me.