Population by sex, age, citizenship, labour status and NUTS 2 regions - lfst_r_lfsd2pwn
Data - Eurostat
Info
Last observation: Annual: 2025 (N = 186,599)
First observation: Annual: 1999 (N = 149,773)
Last data update: 23 jul 2026, 22:22. Last compile: 24 jul 2026, 02:27
Structure
Employment Rate by Citizenship, France
Code
lfst_r_lfsd2pwn %>%
filter(geo == "FR",
age == "Y20-64",
sex == "T",
citizen %in% c("NAT", "FOR"),
wstatus %in% c("EMP", "POP")) %>%
select(citizen, Citizen, wstatus, time, values) %>%
spread(wstatus, values) %>%
mutate(rate = EMP / POP) %>%
year_to_date %>%
ggplot + geom_line(aes(x = date, y = rate, color = Citizen)) +
theme_minimal() +
theme(legend.position = c(0.3, 0.15),
legend.title = element_blank()) +
scale_x_date(breaks = as.Date(paste0(seq(1995, 2100, 5), "-01-01")),
labels = date_format("%Y")) +
xlab("") + ylab("Employment rate, ages 20-64") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1))
Employment Rate of Foreign Citizens by Country
Code
lfst_r_lfsd2pwn %>%
filter(geo %in% c("FR", "DE", "ES", "SE", "NL"),
age == "Y20-64",
sex == "T",
citizen == "FOR",
wstatus %in% c("EMP", "POP")) %>%
select(geo, Geo, wstatus, time, values) %>%
spread(wstatus, values) %>%
mutate(rate = EMP / POP) %>%
year_to_date %>%
left_join(colors, by = c("Geo" = "country")) %>%
mutate(values = rate) %>%
ggplot + geom_line(aes(x = date, y = values, color = color)) +
theme_minimal() + scale_color_identity() + add_5flags +
scale_x_date(breaks = as.Date(paste0(seq(1995, 2100, 5), "-01-01")),
labels = date_format("%Y")) +
xlab("") + ylab("Employment rate of foreign citizens, ages 20-64") +
scale_y_continuous(labels = scales::percent_format(accuracy = 1))
Latest Snapshot: Employment Rate Gap, Nationals vs. Foreigners
Code
latest_y <- lfst_r_lfsd2pwn %>%
filter(age == "Y20-64", sex == "T", citizen %in% c("NAT", "FOR"),
wstatus %in% c("EMP", "POP"), nchar(geo) == 2, !is.na(values)) %>%
summarise(m = max(time)) %>%
pull(m)
lfst_r_lfsd2pwn %>%
filter(nchar(geo) == 2,
age == "Y20-64",
sex == "T",
citizen %in% c("NAT", "FOR"),
wstatus %in% c("EMP", "POP"),
time == latest_y) %>%
select(Geo, citizen, wstatus, values) %>%
spread(wstatus, values) %>%
mutate(rate = round(100 * EMP / POP, 1)) %>%
select(Geo, citizen, rate) %>%
spread(citizen, rate) %>%
filter(!is.na(NAT), !is.na(FOR)) %>%
mutate(gap = round(NAT - FOR, 1)) %>%
arrange(desc(gap)) %>%
print_table_conditional()| Geo | FOR | NAT | gap |
|---|---|---|---|
| Bulgaria | 51.9 | 77.1 | 25.2 |
| Finland | 60.8 | 77.9 | 17.1 |
| France | 61.5 | 76.8 | 15.3 |
| Germany | 69.2 | 83.8 | 14.6 |
| Sweden | 70.2 | 83.0 | 12.8 |
| Hungary | 69.3 | 81.2 | 11.9 |
| Netherlands | 72.8 | 84.4 | 11.6 |
| Serbia | 61.8 | 71.6 | 9.8 |
| Belgium | 65.0 | 74.1 | 9.1 |
| Latvia | 70.3 | 79.2 | 8.9 |
| Austria | 71.4 | 79.6 | 8.2 |
| Switzerland | 77.7 | 84.6 | 6.9 |
| Norway | 73.7 | 80.4 | 6.7 |
| Spain | 67.0 | 73.5 | 6.5 |
| Iceland | 81.8 | 86.7 | 4.9 |
| Romania | 64.4 | 69.0 | 4.6 |
| Estonia | 78.4 | 82.4 | 4.0 |
| Cyprus | 79.3 | 82.1 | 2.8 |
| Italy | 66.8 | 67.6 | 0.8 |
| Slovenia | 77.8 | 78.4 | 0.6 |
| Portugal | 79.8 | 79.6 | -0.2 |
| Lithuania | 80.4 | 80.0 | -0.4 |
| Czechia | 83.6 | 82.8 | -0.8 |
| Greece | 72.1 | 71.0 | -1.1 |
| IE Ireland | 81.6 | 79.8 | -1.8 |
| North Macedonia | 66.5 | 63.7 | -2.8 |
| Poland | 83.8 | 78.7 | -5.1 |
| Croatia | 80.5 | 74.3 | -6.2 |
| LU Luxembourg | 77.3 | 70.3 | -7.0 |
| Slovakia | 85.9 | 78.0 | -7.9 |