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?
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.
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:
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.
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.
First, we were interested in how overall youth labor market conditions evolved over the most recent year. To see whether the youth labor market is stable or volatile in the short term, we created a line chart of monthly employment, unemployment, and labor force participation rates for youths aged 15–29 (Total sex) from October 2024 to October 2025.
# Line graph of monthly trends (Age 15–29, Total)
ggplot(youth_15_29_total,
aes(x = time, y = value, color = indicator)) +
geom_line(linewidth = 1) +
scale_x_date(date_breaks = "1 month", date_labels = "%y-%m") +
labs(
title = "Monthly trends in youth labor indicators (Age 15–29, Total)",
x = "Month",
y = "Value (%)",
color = "Indicator"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
This figure shows that all three indicators stay within a moderate band but display clear month-to-month movements. Unemployment peaks in early 2025 and then declines toward the summer, while employment and participation move in the opposite direction, suggesting sensitivity to seasonal and short-term factors rather than a continuous crisis.
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.
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).
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.
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.