Executive summary

This report analyzes recent youth labor market conditions in South Korea using official statistics from the Korean Statistical Information Service (KOSIS). We focus on young people aged 15–29 (total sex) and examine three core indicators: the employment rate, the unemployment rate, and the labor force participation rate. The data cover a one-year period from October 2024 to October 2025 and provide monthly observations for this age group.

On average, youths aged 15–29 show an employment rate of around the mid-40% range, a labor force participation rate in the high-40% range, and an unemployment rate in the mid-single digits. However, these indicators exhibit visible month-to-month fluctuations rather than a perfectly stable pattern. In particular, we identify a sharp rise in youth unemployment in February 2025 (a “February shock”) followed by a partial recovery around May 2025. This dynamic appears to be related to seasonal factors such as graduation timing, recruitment cycles, and adjustments in part-time and service jobs.

The analysis proceeds in three steps. First, we construct a tidy dataset from the original wide KOSIS table and summarize the three youth labor market indicators. Second, we visualize recent monthly trends and compare different youth age groups and sexes in the most recent month. Third, we explore the relationships among the three indicators and highlight notable turning points in youth employment and unemployment.

Overall, the results show that youth employment, unemployment, and labor force participation for ages 15–29 remained within a moderate range but were sensitive to short-term shocks. Teenagers (15–19) experience much lower employment and participation than those in their twenties, while gender differences within each age group are relatively small. These findings suggest that “youth” is not a homogeneous category and that policy discussions should pay attention to subgroup differences when designing youth employment support measures.

In this project, we address the following research question:
How have the employment, unemployment, and labor force participation rates for Korean youths aged 15–29 changed over the most recent year, and what do these short-term patterns reveal about the internal differences within the youth population by age and sex?

Data background

In South Korea, many university students and young adults in their early twenties feel growing anxiety about finding stable jobs. Even after investing years in higher education, repeated failures in recruitment processes, reliance on precarious work, and uncertainty about when they will “properly” enter the labor market contribute to stress and discouragement. At the same time, Korea is rapidly aging, which makes the successful transition of young people into stable employment crucial for both individual life chances and the long-term health of the labor market.

To understand how youths are currently positioned in the labor market, we focus on three standard indicators used in official labor statistics: the employment rate, the unemployment rate, and the labor force participation rate.

The data come from the Korean Statistical Information Service (KOSIS), specifically the Economically Active Population Survey table titled “Economically active population by sex and age group” (in Korean: “성/연령별 경제활동인구”).

The table provides monthly statistics by sex (Total, Male, Female) and detailed age groups (for example 15–19, 15–24, 15–29, 20–29, 30–39, and 60 and over). For each month from October 2024 to October 2025, it reports both counts (economically active population, employed, unemployed, not economically active) and rates (labor force participation, unemployment, employment).

For this project, we mainly analyze youths aged 15–29, with occasional comparisons to 15–19, 15–24, and 20–29. Our primary focus is on the Total sex category, though we also compare Male and Female in one figure to show gender differences. The time window is restricted to October 2024–October 2025, which allows us to describe short-term monthly changes.

This dataset is appropriate for our purpose because it is publicly available, nationally representative, and directly focused on labor market outcomes. It provides a clear empirical basis for describing short-term changes in youth employment, unemployment, and labor force participation in South Korea.

Data cleaning

The raw KOSIS file is downloaded as a CSV with Korean variable names and a wide layout.
Each row corresponds to a combination of sex and age group, while each column after the first two stores a month–indicator combination. The first row contains the indicator labels (such as employment rate, unemployment rate, and labor force participation rate), and the remaining rows contain numeric values with commas.

For the analysis, we convert this wide table into a tidy data set. The main cleaning steps are:

  1. Read the original CSV file and separate the header row (indicator labels) from the numeric rows.
  2. Reshape the data into a long format so that each row corresponds to one sex–age group–month–indicator combination.
  3. Create English labels for indicators and sex, and define a unified age_group variable where the 15–29 category is labeled as “Age 15–29”.
  4. Filter the data to youths aged 15–29 and the total sex category, and construct a proper Date variable for each month.
  5. Produce a simple summary table of the three key indicators to check that the cleaned values are reasonable.

The code below implements these data cleaning steps and creates the objects used in all subsequent figures.

knitr::opts_chunk$set(echo = TRUE)

library(readr)
library(dplyr)
library(tidyr)
library(ggplot2)
library(lubridate)
library(scales)
library(ggrepel)

# 1. Read the raw KOSIS CSV
youth_raw <- read_csv("성_연령별_경제활동인구_20251120141336.csv")

# 2. Extract indicator labels from the first row (header row)
header_long <- youth_raw %>%
  slice(1) %>%
  pivot_longer(
    cols = -c(성별, 연령계층별),
    names_to  = "time_code",
    values_to = "indicator_label"
  )

# 3. Reshape numeric data rows to long format
data_long <- youth_raw %>%
  slice(-1) %>%                        # drop the header row
  pivot_longer(
    cols = -c(성별, 연령계층별),
    names_to  = "time_code",
    values_to = "value"
  )

# 4. Create tidy labels for indicators, sex, and age_group
youth_tidy <- data_long %>%
  fill(성별, .direction = "down") %>%  # fill down missing sex values
  left_join(header_long %>% select(time_code, indicator_label),
            by = "time_code") %>%
  mutate(
    value = as.numeric(gsub(",", "", value)),
    indicator = case_when(
      indicator_label == "고용률 (%)"         ~ "Employment rate",
      indicator_label == "실업률 (%)"         ~ "Unemployment rate",
      indicator_label == "경제활동참가율 (%)" ~ "Labor force participation rate",
      TRUE                                   ~ NA_character_
    ),
    sex = case_when(
      성별 == "계"   ~ "Total",
      성별 == "남자" ~ "Male",
      성별 == "여자" ~ "Female",
      TRUE          ~ as.character(성별)
    ),
    # Keep all age groups, but relabel 15–29 in English
    age_group = case_when(
      연령계층별 == "15 - 29세" ~ "Age 15–29",
      TRUE                      ~ as.character(연령계층별)
    )
  ) %>%
  filter(!is.na(indicator))

# 5. Subset youths aged 15–29 (Total sex) and create a Date variable
youth_15_29_total <- youth_tidy %>%
  filter(age_group == "Age 15–29",
         sex       == "Total") %>%
  mutate(
    year  = substr(time_code, 1, 4),
    month = substr(time_code, 6, 7),
    time  = as.Date(paste(year, month, "01", sep = "-"))
  ) %>%
  arrange(time)

# 6. Check the summary statistics for key indicators (Age 15–29, Total)
youth_summary <- youth_15_29_total %>%
  group_by(indicator) %>%
  summarise(
    mean = mean(value, na.rm = TRUE),
    sd   = sd(value,   na.rm = TRUE),
    min  = min(value,  na.rm = TRUE),
    max  = max(value,  na.rm = TRUE),
    .groups = "drop"
  )

youth_summary
## # A tibble: 3 × 5
##   indicator                       mean    sd   min   max
##   <chr>                          <dbl> <dbl> <dbl> <dbl>
## 1 Employment rate                45.2  0.566  44.3  46.2
## 2 Labor force participation rate 48.0  0.687  47.1  49.5
## 3 Unemployment rate               5.99 0.876   4.8   7.5

Table 1 summarizes the basic descriptive statistics for the three indicators among youths aged 15–29 (Total sex). On average, the employment rate is approximately 45%, the labor force participation rate is around 48%, and the unemployment rate averages around 6.0%. The standard deviations indicate that while the overall levels are stable, there is noticeable month-to-month variation, particularly in the unemployment rate relative to its mean.

Additional figure: Distribution of youth labor market indicators (Age 15–29, Total)

To get a first impression of the overall level and variability of each indicator, we also examine the distributions of the employment rate, unemployment rate, and labor force participation rate for youths aged 15–29 over the one-year period.

ggplot(youth_15_29_total, aes(x = value)) +
  geom_histogram(
    aes(fill = indicator),
    bins = 10,
    color = "white",
    alpha = 0.9
  ) +
  geom_density(linewidth = 1, color = "black") +
  facet_wrap(~ indicator, scales = "free") +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title = "Distribution of youth labor market indicators (Age 15–29, Total)",
    x     = "Value (%)",
    y     = "Density"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none"
  )

These histograms and density curves show that the three indicators remain within relatively narrow bands over the year, which is consistent with the moderate ranges observed in the summary statistics.

Individual figures

Figure 2: Youth age groups and sex in the latest month

Next, we wanted to see how “youth” is internally differentiated by age and gender. To do this, we created a bar chart that compares employment, unemployment, and labor force participation rates across several youth-related age groups (15–19, 15–24, 15–29, 20–29) and by sex (Male, Female) in the most recent month of the dataset.

# Select youth-related age groups in the original labels

target_age_raw <- c("15 - 19세", "15 - 24세", "15 - 29세", "20 - 29세")

age_sex_data <- youth_tidy %>%
filter(연령계층별 %in% target_age_raw,
sex %in% c("Male", "Female")) %>%
mutate(
age_group_en = case_when(
연령계층별 == "15 - 19세" ~ "Age 15–19",
연령계층별 == "15 - 24세" ~ "Age 15–24",
연령계층별 == "15 - 29세" ~ "Age 15–29",
연령계층별 == "20 - 29세" ~ "Age 20–29",
TRUE ~ as.character(연령계층별)
),
year  = substr(time_code, 1, 4),
month = substr(time_code, 6, 7),
time  = as.Date(paste(year, month, "01", sep = "-"))
)

# Most recent month in the data

latest_time <- max(age_sex_data$time, na.rm = TRUE)

# One value per indicator × age group × sex in that month

latest_summary <- age_sex_data %>%
filter(time == latest_time) %>%
group_by(indicator, age_group_en, sex) %>%
summarise(
value = mean(value, na.rm = TRUE),
.groups = "drop"
)

# Bar chart

ggplot(latest_summary,
aes(x = age_group_en, y = value, fill = sex)) +
geom_col(position = "dodge") +
facet_wrap(~ indicator, scales = "free_y") +
labs(
title = "Youth labor market indicators by age group and sex (latest month)",
x     = "Age group",
y     = "Value (%)",
fill  = "Sex"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

This chart highlights a clear structural gap within youth. Teenagers aged 15–19 have much lower employment and participation rates than those in their twenties, while gender differences within each age group are relatively small. This supports the idea that “youth” is not a homogeneous group and that very young people face higher entry barriers to the labor market.

Figure 3: Relationships among labor market indicators

We also explored the structural relationships between the key indicators. Scatterplots allow us to see how unemployment relates to employment and labor force participation across different age groups.

library(ggrepel)

# Prepare data for scatterplots: translate labels and pivot to wide format
scatter_data <- youth_tidy %>%
  mutate(
    year       = substr(time_code, 1, 4),
    month      = substr(time_code, 6, 7),
    time_label = paste0(substr(year, 3, 4), "-", month),
    age_group_en = case_when(
      age_group == "15 - 19세"  ~ "Age 15–19",
      age_group == "20 - 29세" ~ "Age 20–29",
      age_group == "Age 15–29" ~ "Age 15–29",
      TRUE ~ age_group
    )
  ) %>%
  filter(age_group_en %in% c("Age 15–19", "Age 15–29", "Age 20–29")) %>%
  select(age_group_en, sex, time_label, indicator, value) %>%
  pivot_wider(
    names_from  = indicator,
    values_from = value
  )

# Plot 1: Relationship between Labor Force Participation and Employment
p_act_emp <- ggplot(
  scatter_data,
  aes(
    x     = `Labor force participation rate`,
    y     = `Employment rate`,
    color = age_group_en
  )
) +
  geom_point(na.rm = TRUE, size = 3, alpha = 0.7) +
  geom_smooth(method = "lm", se = FALSE, linetype = "dashed", alpha = 0.5) +
  facet_wrap(~ sex) +
  labs(
    title = "Strong positive correlation: Participation vs Employment",
    subtitle = "Higher participation tends to coincide with higher employment across youth groups",
    x     = "Labor force participation rate (%)",
    y     = "Employment rate (%)",
    color = "Age group"
  ) +
  theme_minimal()

# Plot 2: Relationship between Employment and Unemployment
p_emp_unemp <- ggplot(
  scatter_data,
  aes(
    x     = `Employment rate`,
    y     = `Unemployment rate`,
    color = age_group_en
  )
) +
  geom_point(na.rm = TRUE, size = 3, alpha = 0.7) +
  facet_wrap(~ sex) +
  labs(
    title = "Employment vs Unemployment rates",
    x     = "Employment rate (%)",
    y     = "Unemployment rate (%)",
    color = "Age group"
  ) +
  theme_minimal()

# Display and Save plots
p_act_emp

p_emp_unemp

ggsave("images/figure3_relationship_1.png", plot = p_act_emp, width = 10, height = 6)
ggsave("images/figure3_relationship_2.png", plot = p_emp_unemp, width = 10, height = 6)

The scatterplots reveal a strong positive correlation between labor force participation and employment rates (top chart). This implies that when more young people enter the labor market, they are generally finding jobs rather than just increasing the unemployment count. The comparison between age groups clearly shows that those in their 20s (Age 20–29) operate in a distinct cluster with significantly higher engagement than teenagers (Age 15–19).

Figure 4: Turning points in youth employment and unemployment

Finally, we were interested in whether there are specific months when youth employment and unemployment move unusually sharply—short-term “turning points” rather than smooth trends. To capture this, we computed month-to-month changes in the employment and unemployment rates for youths aged 15–29 (Total sex) and highlighted the months with the largest increases and decreases.

# Prepare youth 15–29, Total with Date variable (if not already restricted)

youth_15_29_recent <- youth_15_29_total %>%
filter(time >= as.Date("2024-10-01"),
time <= as.Date("2025-10-01")) %>%
arrange(time)

# Helper function to compute top increases and decreases

get_turning_points <- function(df, indicator_name, n_points = 1) {
series <- df %>%
filter(indicator == indicator_name) %>%
arrange(time) %>%
mutate(change = value - dplyr::lag(value))

top_inc <- series %>%
slice_max(change, n = n_points, with_ties = FALSE)

top_dec <- series %>%
slice_min(change, n = n_points, with_ties = FALSE)

list(series = series,
turning = bind_rows(top_inc, top_dec))
}

# Employment rate turning points

emp_list    <- get_turning_points(youth_15_29_recent, "Employment rate", n_points = 1)
emp_series  <- emp_list$series
emp_turning <- emp_list$turning

p_emp_turn <- ggplot(emp_series,
aes(x = time, y = value)) +
geom_line(linewidth = 1) +
geom_point() +
geom_point(data = emp_turning,
aes(x = time, y = value),
color = "blue",
size  = 3) +
geom_text(
data = emp_turning,
aes(label = paste0(format(time, "%Y-%m"),
"\nΔ=", round(change, 1))),
vjust = -1,
size  = 3
) +
scale_x_date(date_breaks = "1 month", date_labels = "%y-%m") +
labs(
title = "Employment rate (Age 15–29, Total) with largest monthly changes",
x     = "Month",
y     = "Employment rate (%)"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Unemployment rate turning points

unemp_list    <- get_turning_points(youth_15_29_recent, "Unemployment rate", n_points = 1)
unemp_series  <- unemp_list$series
unemp_turning <- unemp_list$turning

p_unemp_turn <- ggplot(unemp_series,
aes(x = time, y = value)) +
geom_line(linewidth = 1) +
geom_point() +
geom_point(data = unemp_turning,
aes(x = time, y = value),
color = "red",
size  = 3) +
geom_text(
data = unemp_turning,
aes(label = paste0(format(time, "%Y-%m"),
"\nΔ=", round(change, 1))),
vjust = -1,
size  = 3
) +
scale_x_date(date_breaks = "1 month", date_labels = "%y-%m") +
labs(
title = "Unemployment rate (Age 15–29, Total) with largest monthly changes",
x     = "Month",
y     = "Unemployment rate (%)"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

p_emp_turn

p_unemp_turn

These annotated plots clearly show the “February shock” and “May recovery” in youth unemployment and the corresponding movements in employment. They visualize periods when short-term conditions changed more abruptly than usual, helping to link the descriptive statistics to real turning points in the youth labor market.

Conclusion

This project examined recent monthly trends in youth labor market indicators in South Korea using official KOSIS statistics from October 2024 to October 2025. We focused on employment, unemployment, and labor force participation rates among youths aged 15–29, and used a combination of descriptive statistics and visualizations to summarize recent conditions.

First, the time-series and comparative plots showed that all three indicators stayed within a relatively moderate range but exhibited clear month-to-month movements. Youth unemployment rose from late 2024 to a peak in early 2025 and then declined again toward the spring and summer, while employment and labor force participation moved in the opposite direction. This pattern suggests that the youth labor market is not in a state of permanent crisis but is quite sensitive to short-term shocks and seasonal factors such as graduation timing and recruitment schedules.

Second, a comparison of different youth age groups in the latest month highlighted a structural gap within the broad 15–29 category. Teenagers aged 15–19 show much lower employment and labor force participation rates than young adults in their twenties, whereas gender differences within each age group are relatively small. In other words, “youth” is not a homogeneous group: very young people face higher entry barriers than those in their mid-20s, who are already more strongly attached to the labor market.

Third, the turning-point analysis for the 15–29 age group identified a “February shock” and a “May recovery” in the unemployment rate, together with a noticeable rebound in the employment rate in spring. These short-term jumps and drops are consistent with typical seasonal mechanisms, such as the adjustment of temporary and part-time jobs and the inflow and outflow of young job seekers around the graduation and hiring season. Even when the overall level of youth employment does not change dramatically, such volatility can still create instability for individuals who are trying to make the transition from school to work.

From a policy perspective, these findings point to the need for a two-track approach. For early youths (15–19), policy should focus on lowering entry barriers through vocational training, career guidance, and school-to-work transition programs. For young adults (20–29), it is more important to stabilize short-term fluctuations—for example, by smoothing the “graduation cliff” around February and expanding stable, entry-level positions so that temporary spikes in unemployment do not turn into long-term scarring.

At the same time, our analysis is constrained by the relatively short one-year window and by the use of aggregated statistics rather than micro-level data. We cannot control for factors such as education level, region, or industry, and we cannot fully separate seasonal effects from broader macroeconomic changes. Future research could extend the time frame, compare pre- and post-COVID periods, or link individual-level characteristics (for example, field of study or region) to labor market outcomes in order to provide a more detailed picture of youth employment in South Korea. Despite these limitations, this project offers a clear, data-driven snapshot of how Korean youths aged 15–29 are currently positioned in the labor market and provides a useful starting point for policy discussions about youth employment support.