adding missing data, adding preliminary exploration

This commit is contained in:
Pablo Antonio Lillo Cea 2026-05-08 10:09:14 +02:00
parent 9ca2f78396
commit 1631adfb02
17 changed files with 1488 additions and 14 deletions

BIN
RQ_municipalities.pdf Normal file

Binary file not shown.

545
RQ_municipalities.qmd Normal file
View file

@ -0,0 +1,545 @@
---
title: "Educational offer and attainment across Swedish municipalities"
subtitle: "Preliminary exploration for QRM"
date: today
format:
pdf:
toc: true
number-sections: true
fig-pos: "H"
geometry: margin=2.5cm
fontsize: 11pt
execute:
echo: false
warning: false
message: false
---
```{r setup}
library(tidyverse)
library(FactoMineR)
library(ggrepel)
library(knitr)
library(kableExtra)
library(showtext)
font_add_google("Source Sans 3", "source_sans_3")
showtext_auto()
# 01 - Load preprocessed data -----------------------------------------------------
m_sample <- read_rds("data/processed/m_sample.rds")
ca <- read_rds("data/processed/ca_exploratory.rds")
var_groups <- read_rds("data/processed/ca_var_groups.rds")
edu_offer <- read_rds("data/processed/edu_offer.rds")
att_summary <- read_rds("data/processed/attainment_summary.rds")
# 02 - County lookup --------------------------------------------------------------
county_names <- c(
"01" = "Stockholm", "03" = "Uppsala", "04" = "Södermanland",
"05" = "Östergötland", "06" = "Jönköping", "07" = "Kronoberg",
"08" = "Kalmar", "09" = "Gotland", "10" = "Blekinge",
"12" = "Skåne", "13" = "Halland", "14" = "Västra Götaland",
"17" = "Värmland", "18" = "Örebro", "19" = "Västmanland",
"20" = "Dalarna", "21" = "Gävleborg", "22" = "Västernorrland",
"23" = "Jämtland", "24" = "Västerbotten", "25" = "Norrbotten"
)
m_sample <- m_sample |>
mutate(county = county_names[str_sub(code, 1, 2)])
edu_offer <- edu_offer |>
mutate(county = county_names[str_sub(code, 1, 2)])
att_summary <- att_summary |>
left_join(m_sample |> select(code, municipality, county), by = "code")
# 03 - Key municipalities for labels ----------------------------------------------
key_munis <- c("Stockholm", "Göteborg", "Malmö", "Uppsala", "Umeå",
"Lund", "Linköping", "Kiruna", "Danderyd", "Filipstad")
```
# RQ1: Educational attainment over time and its relationship to educational offer
Educational attainment varies substantially across Swedish municipalities and has risen throughout this century. The pace of change is uneven. Urban and university municipalities have consistently outpaced smaller, industrial, or peripheral ones, widening the educational gap in the population. The following analyses draw on register data from Statistics Sweden for the population aged 25--64 in all 290 municipalities, at five time-points (2000, 2005, 2010, 2015, 2022). educational offer is measured from the 2024 school-unit registry and the UKÄ register.
## Trends in post-secondary attainment
```{r fig-rq1-trends, fig.width=8, fig.height=5.5, fig.cap="Share of 25--64 year olds with post-secondary education (ISCED 5+), all 290 municipalities, 2000--2022. Grey lines = individual municipalities; thick blue line = national median; shaded band = interquartile range. Selected municipalities labelled."}
# National quartiles per year
nat_stats <- att_summary |>
group_by(year) |>
summarise(
med = median(pct_postsec, na.rm = TRUE),
q25 = quantile(pct_postsec, 0.25, na.rm = TRUE),
q75 = quantile(pct_postsec, 0.75, na.rm = TRUE)
)
# Labels at endpoint (2022)
label_df <- att_summary |>
filter(year == 2022, municipality %in% key_munis)
ggplot() +
geom_line(
data = att_summary,
aes(x = year, y = pct_postsec, group = municipality),
colour = "grey72", linewidth = 0.3, alpha = 0.6
) +
geom_ribbon(
data = nat_stats, aes(x = year, ymin = q25, ymax = q75),
fill = "#2171b5", alpha = 0.15
) +
geom_line(
data = nat_stats, aes(x = year, y = med),
colour = "#2171b5", linewidth = 1.1
) +
geom_line(
data = filter(att_summary, municipality %in% key_munis),
aes(x = year, y = pct_postsec, group = municipality),
colour = "#cb181d", linewidth = 0.55
) +
geom_text_repel(
data = label_df,
aes(x = year, y = pct_postsec, label = municipality),
direction = "y",
nudge_x = 1.5,
segment.size = 0.3,
size = 2.8,
hjust = 0
) +
scale_x_continuous(
breaks = c(2000, 2005, 2010, 2015, 2022),
limits = c(2000, 2029)
) +
labs(
x = NULL, y = "% with post-secondary education (ISCED 5+)",
caption = "Source: SCB UF0506B. Blue line = national median; shaded = IQR."
) +
theme_minimal(base_size = 10, base_family = "source_sans_3") +
theme(panel.grid.minor = element_blank())
```
The national median post-secondary share rose from `r round(filter(nat_stats, year==2000)$med, 1)`% in 2000 to `r round(filter(nat_stats, year==2022)$med, 1)`% in 2022. The interquartile range widened over the same period, reflecting growing polarisation between knowledge-economy and peripheral municipalities. Danderyd, Lund, and Solna consistently lead; small industrial municipalities in Värmland, Bergslagen, and Norrland remain clustered at the bottom.
## Attainment and educational offer
```{r fig-rq1-scatter, fig.width=7.5, fig.height=5, fig.cap="2022 post-secondary attainment vs. number of upper-secondary units, by type of higher education presence. Point size = number of komvux units. Municipalities with no gymnasieskola (n=39) omitted. Selected municipalities labelled."}
att_22 <- att_summary |>
filter(year == 2022) |>
left_join(
edu_offer |> select(code, gymnasieskola_n_total, komvux_n_total,
university_n_total, university_college_n_total),
by = "code"
) |>
mutate(
he_cat = case_when(
university_n_total > 0 ~ "University",
university_college_n_total > 0 ~ "University college",
TRUE ~ "No HE institution"
) |> factor(levels = c("No HE institution", "University college", "University"))
) |>
filter(gymnasieskola_n_total > 0)
label_22 <- filter(att_22, municipality %in% key_munis)
ggplot(att_22, aes(x = gymnasieskola_n_total, y = pct_postsec, colour = he_cat)) +
geom_point(aes(size = komvux_n_total), alpha = 0.6) +
geom_text_repel(
data = label_22,
aes(label = municipality),
size = 2.8, max.overlaps = 15, show.legend = FALSE
) +
scale_colour_manual(
values = c("No HE institution" = "grey60",
"University college" = "#fd8d3c",
"University" = "#cb181d"),
name = NULL
) +
scale_size_continuous(name = "Komvux units", range = c(1, 6)) +
scale_x_log10(breaks = c(1, 2, 5, 10, 20, 50, 100)) +
labs(
x = "Number of gymnasieskola units (log scale)",
y = "% with post-secondary education (2022)",
caption = "Point size = number of komvux units."
) +
theme_minimal(base_size = 10, base_family = "source_sans_3") +
theme(legend.position = "bottom", panel.grid.minor = element_blank())
```
Municipalities with a university consistently show higher post-secondary attainment than those without, regardless of overall size. The relationship extends to komvux. Municipalities with a larger adult education offer tend to have higher attainment levels. These associations suggest a long-term structural co-constitution of educational offer and educated populations rather than a simple effect in one direction.
# RQ2: Distribution of educational offer across municipalities
The supply of education varies substantially by level, institution type, and geography. The following describes the landscape of educational offer using the Skolverket school-unit registry and the UKÄ register of higher education institutions. Both reflect the state of educational offer at the time of analysis; the CA in Section 3 uses 2022 population data, and the school registry is a close but not identical snapshot. Two institution types remain outside the current dataset: *yrkeshögskola* (vocational higher education; source MYH) and *folkhögskola* (folk high schools; source Folkbildningsrådet).
## Coverage by institution type
```{r tbl-coverage}
#| tbl-cap: "educational offer by institution type across 290 Swedish municipalities."
offer_vars <- tribble(
~var, ~label,
"forskoleklass", "Förskoleklass",
"grundskola", "Grundskola",
"anpassad_grundskola", "Anpassad grundskola",
"gymnasieskola", "Gymnasieskola",
"komvux", "Komvux",
"sfi", "SFI (within komvux)",
"anpassad_gymnasieskola", "Anpassad gymnasieskola",
"specialskola", "Specialskola",
"sameskola", "Sameskola",
"university_college", "University college",
"university", "University"
)
coverage_tbl <- offer_vars |>
mutate(
n_tot = map_int(var, \(v) sum(edu_offer[[paste0(v,"_n_total")]] > 0, na.rm=TRUE)),
pct = round(100 * n_tot / 290, 0),
med_n = map_dbl(var, \(v) {
x <- edu_offer[[paste0(v,"_n_total")]]; median(x[x>0], na.rm=TRUE)
}),
max_n = map_int(var, \(v) max(edu_offer[[paste0(v,"_n_total")]], na.rm=TRUE)),
pct_priv = map_dbl(var, \(v) {
tot <- sum(edu_offer[[paste0(v,"_n_total")]], na.rm=TRUE)
priv <- sum(edu_offer[[paste0(v,"_n_private")]], na.rm=TRUE)
if(tot==0 || is.na(priv)) return(NA_real_)
round(100*priv/tot, 1)
})
)
coverage_tbl |>
transmute(
`Institution type` = label,
`Municipalities (n)` = n_tot,
`Coverage (%)` = pct,
`Median units*` = round(med_n, 1),
`Max units` = max_n,
`Private share (%)` = pct_priv
) |>
kbl(
booktabs = TRUE, linesep = ""
) |>
kable_styling(font_size = 9, latex_options = c("hold_position", "scale_down")) |>
footnote(
general = "Median units computed among municipalities with at least one unit. Yrkeshögskola and folkhögskola not included (data pending).",
general_title = "Note:",
footnote_as_chunk = TRUE
)
```
Primary and lower secondary education is effectively universal. Every municipality has both förskoleklass and grundskola units. Gymnasieskola is present in 87% of municipalities; the remaining 13% (mostly sparsely populated northern or island municipalities) rely on inter-municipal agreements. Komvux covers 90% and SFI 87% of municipalities. Higher education is concentrated with only 11 municipalities hosting a university and 20 hosting a university college, together covering 10% of all municipalities.
## Regional distribution
```{r fig-rq2-region, fig.width=9, fig.height=6, fig.cap="educational offer coverage (\\% of municipalities with at least one unit) by county and selected institution types. Counties ordered from south to north."}
county_order <- c(
"Skåne", "Blekinge", "Halland", "Kronoberg", "Kalmar", "Gotland",
"Jönköping", "Östergötland", "Södermanland", "Västra Götaland",
"Örebro", "Västmanland", "Stockholm", "Uppsala", "Dalarna",
"Värmland", "Gävleborg", "Västernorrland", "Jämtland",
"Västerbotten", "Norrbotten"
)
sel_types <- tribble(
~var, ~label,
"gymnasieskola", "Gymnasieskola",
"komvux", "Komvux",
"sfi", "SFI",
"university_college","University college",
"university", "University"
)
county_coverage <- edu_offer |>
group_by(county) |>
summarise(
across(
all_of(paste0(sel_types$var, "_n_total")),
\(x) 100 * mean(x > 0, na.rm = TRUE)
),
n_munis = n()
) |>
pivot_longer(
-c(county, n_munis),
names_to = "var",
values_to = "pct_with"
) |>
mutate(var = str_remove(var, "_n_total")) |>
left_join(sel_types, by = "var") |>
mutate(county = factor(county, levels = county_order))
ggplot(county_coverage, aes(x = county, y = pct_with, fill = pct_with)) +
geom_col() +
geom_text(aes(label = round(pct_with), y = pmax(pct_with - 5, 3)),
size = 2.2, colour = "white", fontface = "bold") +
facet_wrap(~label, nrow = 2) +
scale_fill_distiller(palette = "YlOrRd", direction = 1, guide = "none") +
scale_y_continuous(labels = \(x) paste0(x,"%"), limits = c(0,105)) +
labs(x = NULL, y = "% of municipalities with ≥1 unit") +
theme_minimal(base_size = 9, base_family = "source_sans_3") +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, size = 7),
panel.grid.major.x = element_blank(),
strip.text = element_text(face = "bold")
)
```
Gymnasieskola coverage approaches 100% in most counties; gaps appear in sparsely populated northern counties (Jämtland, Norrbotten). SFI and komvux gaps are more pronounced in low-density counties. Higher education—universities and university colleges—is geographically clustered with Stockholm, Gothenburg, and Malmö counties accounting for the majority of institutions, while large parts of northern Sweden and smaller coastal counties have no HE institution within their borders.
## Public and private provision
```{r fig-rq2-private, fig.width=8, fig.height=4, fig.cap="Private provision by institution type. Left: share of municipalities with at least one private unit. Right: national aggregate private share (private units as \\% of all units of that type). HE institutions excluded (all classified as public)."}
priv_types <- offer_vars |>
filter(!var %in% c("university", "university_college", "specialskola", "sameskola"))
priv_df <- priv_types |>
mutate(
pct_munis_with_private = map_dbl(var, \(v) {
p <- edu_offer[[paste0(v, "_n_private")]]
100 * mean(p > 0, na.rm = TRUE)
}),
pct_national = map_dbl(var, \(v) {
tot <- sum(edu_offer[[paste0(v, "_n_total")]], na.rm = TRUE)
priv <- sum(edu_offer[[paste0(v, "_n_private")]], na.rm = TRUE)
if (tot == 0) return(NA_real_)
100 * priv / tot
})
) |>
filter(!is.na(pct_national)) |>
mutate(label = fct_reorder(label, pct_national))
p_left <- ggplot(priv_df, aes(y = label, x = pct_munis_with_private)) +
geom_col(fill = "#6baed6") +
geom_text(aes(label = paste0(round(pct_munis_with_private), "%")),
hjust = -0.15, size = 3) +
scale_x_continuous(limits = c(0, 75), labels = \(x) paste0(x, "%")) +
labs(x = "% of municipalities", y = NULL,
title = "Municipalities with ≥1 private unit") +
theme_minimal(base_size = 9, base_family = "source_sans_3") +
theme(panel.grid.minor = element_blank(),
plot.title = element_text(size = 9, face = "bold"))
p_right <- ggplot(priv_df, aes(y = label, x = pct_national)) +
geom_col(fill = "#cb181d") +
geom_text(aes(label = paste0(round(pct_national, 1), "%")),
hjust = -0.15, size = 3) +
scale_x_continuous(limits = c(0, 50), labels = \(x) paste0(x, "%")) +
labs(x = "% of all units (national)", y = NULL,
title = "National private share") +
theme_minimal(base_size = 9, base_family = "source_sans_3") +
theme(panel.grid.minor = element_blank(), axis.text.y = element_blank(),
plot.title = element_text(size = 9, face = "bold"))
library(patchwork)
p_left + p_right
```
Private provision is most common in upper secondary (gymnasieskola) and basic primary (grundskola). The two figures show different aspects of the same phenomenon. At the national level, 35% of all gymnasieskola units and 18% of all grundskola units are privately run. At the municipal level, however, the majority of municipalities have no private gymnasieskola at all: private upper-secondary schools are heavily concentrated in a handful of larger municipalities, particularly in the Stockholm region. Anpassad utbildning and adult education (komvux, SFI) remain almost exclusively municipal.
# RQ3: Educational assets in the CA space and their relationship to educational offer
Correspondence analysis (CA) is applied to a contingency table in which the 290 municipalities are rows and population-composition variables are columns—all measured as resident counts: age structure (11 groups), educational attainment of Swedish-born men and women (4 levels each), employment by activity sector, and birth country (Swedish-born vs. foreign-born). Two municipalities are close when their resident profiles are similar, regardless of size. Educational offer variables enter the analysis as *supplementary* columns. This section first describes the CA axes, then examines how educational offer relates to them.
## CA structure: eigenvalues and active variables
```{r tbl-ca-eig}
#| tbl-cap: "CA eigenvalues for the first seven dimensions."
eig_df <- as.data.frame(ca$eig[1:7, ]) |>
rownames_to_column("Dimension") |>
mutate(Dimension = str_replace(Dimension, "^dim ", "Dim ")) |>
transmute(
Dimension,
Eigenvalue = round(eigenvalue, 4),
`% variance` = round(`percentage of variance`, 1),
`Cumulative %` = round(`cumulative percentage of variance`, 1)
)
kbl(eig_df, booktabs = TRUE, linesep = "") |>
kable_styling(font_size = 9, latex_options = "hold_position")
```
```{r tbl-ca-active}
#| tbl-cap: !expr paste0("Active variables in the CA (*n* = ", length(var_groups$active), "). All measure counts of residents.")
domain_labels <- c(
"Age" = "Age structure (11 groups)",
"Edu (men)" = "Education level, Swedish-born men (4 levels)",
"Edu (women)" = "Education level, Swedish-born women (4 levels)",
"Empl. sector" = "Employment by activity sector",
"Birth country"= "Birth country (Sweden-born vs. foreign-born)"
)
active_counts <- tibble(
Domain = names(domain_labels),
Description = unname(domain_labels),
`Variables (n)` = c(
sum(str_detect(var_groups$active, "^age_")),
sum(str_detect(var_groups$active, "^education_level_of_swedish_men_")),
sum(str_detect(var_groups$active, "^education_level_of_swedish_women_")),
sum(str_detect(var_groups$active, "^employment_by_activity_sectors_")),
sum(str_detect(var_groups$active, "^birth_country_"))
)
)
kbl(active_counts, booktabs = TRUE, linesep = "") |>
kable_styling(font_size = 9, latex_options = "hold_position")
```
```{r tbl-ca-contrib}
#| tbl-cap: "Top six active-variable contributions (%) to Dimensions 1--3."
contrib_df <- ca$col$contrib |>
as.data.frame() |>
rownames_to_column("variable")
top_contrib <- map_dfr(1:3, \(d) {
col <- paste0("Dim ", d)
contrib_df |>
slice_max(.data[[col]], n = 6) |>
transmute(
Dimension = paste0("Dim ", d),
Variable = variable,
`Contribution (%)` = round(.data[[col]], 1)
)
})
top_contrib |>
mutate(Variable = Variable |>
str_replace("^education_level_of_swedish_men_", "Edu men: ") |>
str_replace("^education_level_of_swedish_women_", "Edu women: ") |>
str_replace("^employment_by_activity_sectors_", "Sector: ") |>
str_replace("^birth_country_", "Birth country: ") |>
str_replace("^age_", "Age: ") |>
str_replace_all("_", " ")
) |>
kbl(booktabs = TRUE, linesep = "") |>
kable_styling(font_size = 9, latex_options = c("hold_position", "scale_down")) |>
collapse_rows(columns = 1, latex_hline = "major")
```
The first two dimensions together account for `r round(sum(ca$eig[1:2, "percentage of variance"]), 1)`% of total inertia. Dimension 1 (`r round(ca$eig[1, "percentage of variance"], 1)`%) is the dominant axis capturing a rural--urban opposition. Its inertia is distributed across five variable themes: the foreign-born share (16.4%), post-secondary attainment among Swedish-born men and women (11.2% and 6.1%), and a sectoral contrast between personal and cultural services on one side and industrial and agricultural employment on the other (8.4%, 8.0%, 6.1%). The placement of immigration and education on the same axis suggest that in Sweden, both concentrations are features of the same metropolitan geography. At the positive pole (right) sit Stockholm, Göteborg, Malmö, and university towns such as Lund and Uppsala; at the negative pole (left) sit small, peripheral municipalities.
Dimension 2 (`r round(ca$eig[2, "percentage of variance"], 1)`%) identifies a secondary opposition that is structurally distinct from Dimension 1. Here, birth-country alone contributes 48.6% of the dimension's inertia, dwarfing all other variables. This axis separates suburban municipalities with an exceptionally high concentration of foreign-born residents like Södertälje and Botkyrka from both metropolitan education centres and rural municipalities.
Dimension 3 (`r round(ca$eig[3, "percentage of variance"], 1)`%) represents a third opposition. Mining and manufacturing employment contributes 34.0% of its inertia, and a young adult age profile adds 16.3%. This axis picks out resource-extraction municipalities like Kiruna, Gällivare, and similar northern towns, whose population structure is shaped by industrial labour demand rather than either urban services or immigration patterns.
## Correlations between CA dimensions and educational offer
```{r fig-rq3-heatmap, fig.width=8, fig.height=5.5, fig.cap="Pearson correlations between CA row scores (Dimensions 1--3) and educational offer indicators. Only variables with $|r| \\geq 0.15$ on at least one dimension are shown. Labels printed where $|r| \\geq 0.25$."}
ca_coords <- as.data.frame(ca$row$coord) |>
rownames_to_column("municipality") |>
rename_with(\(x) str_replace(x, "^Dim ", "Dim_"), starts_with("Dim"))
offer_num <- edu_offer |>
select(municipality, ends_with("_n_total")) |>
rename_with(\(x) str_remove(x, "_n_total"), ends_with("_n_total"))
offer_joined <- ca_coords |>
left_join(offer_num, by = "municipality")
offer_vars_sel <- names(offer_num)[-1]
# Use case_match for exact lookup — avoids substring collision in str_replace chain
clean_label <- function(v) {
case_match(v,
"forskoleklass" ~ "Förskoleklass",
"grundskola" ~ "Grundskola",
"anpassad_grundskola" ~ "Anp. grundskola",
"anpassad_gymnasieskola" ~ "Anp. gymnasieskola",
"gymnasieskola" ~ "Gymnasieskola",
"komvux" ~ "Komvux",
"sfi" ~ "SFI",
"specialskola" ~ "Specialskola",
"sameskola" ~ "Sameskola",
"university_college" ~ "University college",
"university" ~ "University",
.default = v
)
}
cor_mat <- cor(
offer_joined[, paste0("Dim_", 1:3)],
offer_joined[, offer_vars_sel],
use = "pairwise.complete.obs"
)
cor_long <- as.data.frame(cor_mat) |>
rownames_to_column("dimension") |>
pivot_longer(-dimension, names_to = "variable", values_to = "r") |>
filter(!is.na(r))
keep_vars <- cor_long |>
group_by(variable) |>
summarise(max_r = max(abs(r))) |>
filter(max_r >= 0.15) |>
pull(variable)
plot_df <- cor_long |>
filter(variable %in% keep_vars) |>
mutate(
label = clean_label(variable),
dimension = str_replace(dimension, "_", " ")
)
ggplot(plot_df, aes(x = dimension, y = reorder(label, r), fill = r)) +
geom_tile(colour = "white", linewidth = 0.4) +
geom_text(
data = filter(plot_df, abs(r) >= 0.25),
aes(label = sprintf("%.2f", r)),
size = 3
) +
scale_fill_gradient2(
low = "#b2182b", mid = "white", high = "#2166ac",
midpoint = 0, limits = c(-1, 1), name = "r"
) +
labs(x = NULL, y = NULL,
caption = "Correlations with CA row scores. Blue = positive, red = negative.") +
theme_minimal(base_size = 10, base_family = "source_sans_3") +
theme(axis.text.y = element_text(size = 9))
```
```{r fig-rq3-biplot, fig.width=7.5, fig.height=6.5, fig.cap="CA biplot (Dimensions 1--2) with educational offer as vectors. Arrows represent the direction of Pearson correlations with CA row scores (arrow length proportional to $|r|$, scaled for readability). Municipalities shown as grey points; key municipalities labelled."}
scale_fac <- 3.5 # scale correlation vectors to biplot space
rows_bp <- ca_coords |>
left_join(m_sample |> select(municipality), by = "municipality")
offer_arrows <- tibble(variable = offer_vars_sel) |>
mutate(
d1 = map_dbl(variable, \(v) cor(offer_joined$Dim_1, offer_joined[[v]], use="pairwise.complete.obs")),
d2 = map_dbl(variable, \(v) cor(offer_joined$Dim_2, offer_joined[[v]], use="pairwise.complete.obs")),
label = clean_label(variable)
) |>
filter(abs(d1) >= 0.2 | abs(d2) >= 0.2) |>
mutate(d1 = d1 * scale_fac, d2 = d2 * scale_fac)
key_rows <- rows_bp |> filter(municipality %in% key_munis)
dim_pct <- round(ca$eig[1:2, "percentage of variance"], 1)
ggplot() +
geom_point(data = rows_bp,
aes(x = Dim_1, y = Dim_2),
colour = "grey80", size = 0.8, alpha = 0.7) +
geom_segment(data = offer_arrows,
aes(x = 0, y = 0, xend = d1, yend = d2),
arrow = arrow(length = unit(0.18, "cm"), type = "closed"),
colour = "#2166ac", linewidth = 0.65) +
geom_text_repel(data = offer_arrows,
aes(x = d1, y = d2, label = label),
colour = "#2166ac", size = 3,
max.overlaps = 20, force = 3) +
geom_text_repel(data = key_rows,
aes(x = Dim_1, y = Dim_2, label = municipality),
colour = "black", fontface = "bold",
size = 2.8, max.overlaps = 15) +
geom_hline(yintercept = 0, linetype = "dashed", colour = "grey60", linewidth = 0.3) +
geom_vline(xintercept = 0, linetype = "dashed", colour = "grey60", linewidth = 0.3) +
labs(
x = paste0("Dimension 1 (", dim_pct[1], "%)"),
y = paste0("Dimension 2 (", dim_pct[2], "%)"),
caption = "Arrows = educational offer variables (Pearson r × 3.5, threshold |r| ≥ 0.20)."
) +
theme_minimal(base_size = 10, base_family = "source_sans_3") +
theme(panel.grid.minor = element_blank())
```
All offer types correlate positively with Dimension 1, confirming that the volume of educational offer is related to the rural--urban opposition already captured by population composition. Municipalities at the positive pole have more units of every type (grundskola, gymnasieskola, komvux, SFI, and higher education). This reflects the structural co-location of educated populations and educational institutions in the same urban places.
Komvux and SFI correlate positively with Dimension 2, meaning that the municipalities located at the top on this axis—those with the highest foreign-born concentrations—also tend to have more adult and language education relative to their position on Dimension 1. Universities and university colleges show negligible correlation with Dimension 2, consistent with the interpretation that higher education in this space relates to educational attainment (Dimension 1) rather than immigration reception (Dimension 2). The separation of SFI and komvux from higher education suggests that adult integration education and academic provision relate to different municipal profiles.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -0,0 +1,291 @@
code,municipality,forskoleklass_n_total,grundskola_n_total,anpassad_grundskola_n_total,specialskola_n_total,sameskola_n_total,gymnasieskola_n_total,anpassad_gymnasieskola_n_total,komvux_n_total,sfi_n_total,university_college_n_total,university_n_total,forskoleklass_n_public,grundskola_n_public,anpassad_grundskola_n_public,specialskola_n_public,sameskola_n_public,gymnasieskola_n_public,anpassad_gymnasieskola_n_public,komvux_n_public,sfi_n_public,university_college_n_public,university_n_public,forskoleklass_n_private,grundskola_n_private,anpassad_grundskola_n_private,specialskola_n_private,sameskola_n_private,gymnasieskola_n_private,anpassad_gymnasieskola_n_private,komvux_n_private,sfi_n_private,university_college_n_private,university_n_private
0114,Upplands Väsby,14,17,2,0,0,2,0,4,2,0,0,5,7,2,0,0,1,0,4,2,0,0,9,10,0,0,0,1,0,0,0,0,0
0115,Vallentuna,11,13,3,0,0,1,1,0,0,0,0,8,8,1,0,0,1,0,0,0,0,0,3,5,2,0,0,0,1,0,0,0,0
0117,Österåker,16,18,3,0,0,2,0,3,2,0,0,10,12,3,0,0,1,0,3,2,0,0,6,6,0,0,0,1,0,0,0,0,0
0120,Värmdö,17,18,1,0,0,4,1,2,2,0,0,12,13,1,0,0,2,1,2,2,0,0,5,5,0,0,0,2,0,0,0,0,0
0123,Järfälla,19,25,8,0,0,3,1,2,1,0,0,17,22,8,0,0,2,1,2,1,0,0,2,3,0,0,0,1,0,0,0,0,0
0125,Ekerö,12,14,1,0,0,1,1,1,0,0,0,9,11,1,0,0,1,1,1,0,0,0,3,3,0,0,0,0,0,0,0,0,0
0126,Huddinge,30,37,6,0,0,7,2,4,3,1,0,26,30,6,0,0,5,2,4,3,1,0,4,7,0,0,0,2,0,0,0,0,0
0127,Botkyrka,24,27,9,0,0,5,2,2,1,0,0,19,21,9,0,0,4,1,2,1,0,0,5,6,0,0,0,1,1,0,0,0,0
0128,Salem,7,7,1,0,0,1,0,1,1,0,0,4,4,1,0,0,1,0,1,1,0,0,3,3,0,0,0,0,0,0,0,0,0
0136,Haninge,28,31,6,0,0,5,3,1,1,0,0,18,19,6,0,0,3,2,1,1,0,0,10,12,0,0,0,2,1,0,0,0,0
0138,Tyresö,13,16,2,0,0,1,1,3,1,0,0,11,13,2,0,0,1,1,3,1,0,0,2,3,0,0,0,0,0,0,0,0,0
0139,Upplands-Bro,11,14,1,0,0,1,1,3,1,0,0,8,10,1,0,0,1,1,3,1,0,0,3,4,0,0,0,0,0,0,0,0,0
0140,Nykvarn,3,4,2,0,0,1,0,0,0,0,0,3,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
0160,Täby,20,32,4,0,0,8,1,4,2,0,0,13,18,2,0,0,2,1,4,2,0,0,7,14,2,0,0,6,0,0,0,0,0
0162,Danderyd,12,16,3,0,0,4,2,0,0,0,0,8,10,2,0,0,1,1,0,0,0,0,4,6,1,0,0,3,1,0,0,0,0
0163,Sollentuna,30,31,4,0,0,14,2,2,1,0,0,15,17,2,0,0,8,0,2,1,0,0,15,14,2,0,0,6,2,0,0,0,0
0180,Stockholm,206,247,54,3,0,96,12,17,15,11,2,136,142,42,3,0,31,6,17,15,11,2,70,105,12,0,0,65,6,0,0,0,0
0181,Södertälje,30,34,10,0,0,11,4,2,1,0,0,19,21,5,0,0,3,1,2,1,0,0,11,13,5,0,0,8,3,0,0,0,0
0182,Nacka,33,38,5,0,0,14,3,1,1,0,0,19,22,4,0,0,2,3,1,1,0,0,14,16,1,0,0,12,0,0,0,0,0
0183,Sundbyberg,9,12,1,0,0,3,0,2,1,0,0,7,7,1,0,0,1,0,2,1,0,0,2,5,0,0,0,2,0,0,0,0,0
0184,Solna,16,21,5,0,0,9,6,2,2,0,1,9,10,1,0,0,1,2,2,2,0,1,7,11,4,0,0,8,4,0,0,0,0
0186,Lidingö,16,18,1,0,0,3,0,3,2,0,0,11,12,1,0,0,1,0,3,2,0,0,5,6,0,0,0,2,0,0,0,0,0
0187,Vaxholm,4,5,0,0,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0188,Norrtälje,29,34,2,0,0,4,2,2,0,0,0,20,23,1,0,0,1,1,2,0,0,0,9,11,1,0,0,3,1,0,0,0,0
0191,Sigtuna,16,20,3,0,0,8,1,4,2,0,0,13,15,3,0,0,3,1,3,2,0,0,3,5,0,0,0,5,0,1,0,0,0
0192,Nynäshamn,6,6,2,0,0,1,2,1,1,0,0,5,5,2,0,0,1,2,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0305,Håbo,8,8,1,0,0,2,1,1,1,0,0,7,6,1,0,0,2,1,1,1,0,0,1,2,0,0,0,0,0,0,0,0,0
0319,Älvkarleby,4,5,1,0,0,1,0,1,1,0,0,3,4,1,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0330,Knivsta,9,11,1,0,0,1,0,1,1,0,0,7,9,1,0,0,1,0,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0
0331,Heby,7,9,1,0,0,0,0,3,1,0,0,6,8,1,0,0,0,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0360,Tierp,11,12,1,0,0,1,1,3,1,0,0,11,12,1,0,0,1,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0380,Uppsala,59,77,8,0,0,25,5,10,5,1,2,49,57,5,0,0,8,2,10,5,1,2,10,20,3,0,0,17,3,0,0,0,0
0381,Enköping,14,17,2,0,0,1,1,1,1,0,0,11,12,2,0,0,1,1,1,1,0,0,3,5,0,0,0,0,0,0,0,0,0
0382,Östhammar,7,9,1,0,0,3,0,3,1,0,0,7,9,1,0,0,1,0,3,1,0,0,0,0,0,0,0,2,0,0,0,0,0
0428,Vingåker,5,7,2,0,0,1,1,1,1,0,0,4,6,2,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0461,Gnesta,5,5,1,0,0,0,0,1,1,0,0,4,4,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0480,Nyköping,28,34,3,0,0,10,3,4,1,0,0,22,24,3,0,0,4,2,4,1,0,0,6,10,0,0,0,6,1,0,0,0,0
0481,Oxelösund,2,3,1,0,0,0,0,2,1,0,0,2,3,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0482,Flen,8,8,1,0,0,1,1,3,1,0,0,5,5,1,0,0,1,1,3,1,0,0,3,3,0,0,0,0,0,0,0,0,0
0483,Katrineholm,10,13,4,0,0,5,1,1,1,0,0,10,12,4,0,0,5,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0
0484,Eskilstuna,31,33,7,0,0,12,2,3,1,1,0,27,27,7,0,0,7,2,3,1,1,0,4,6,0,0,0,5,0,0,0,0,0
0486,Strängnäs,10,14,2,0,0,2,1,3,1,0,0,6,8,2,0,0,1,1,3,1,0,0,4,6,0,0,0,1,0,0,0,0,0
0488,Trosa,4,6,3,0,0,1,1,1,1,0,0,4,6,3,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0
0509,Ödeshög,2,3,0,0,0,0,0,0,0,0,0,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0512,Ydre,2,3,0,0,0,0,0,0,0,0,0,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0513,Kinda,3,6,2,0,0,0,0,1,1,0,0,3,6,2,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0560,Boxholm,2,2,2,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0561,Åtvidaberg,3,5,1,0,0,1,0,1,1,0,0,3,5,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0562,Finspång,11,13,1,0,0,2,2,1,1,0,0,10,12,1,0,0,1,1,1,1,0,0,1,1,0,0,0,1,1,0,0,0,0
0563,Valdemarsvik,4,5,0,0,0,0,0,0,0,0,0,3,4,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0
0580,Linköping,48,80,8,0,0,28,4,11,4,0,1,42,68,7,0,0,20,4,11,4,0,1,6,12,1,0,0,8,0,0,0,0,0
0581,Norrköping,40,65,10,0,0,29,6,9,4,0,0,33,52,9,0,0,21,6,9,4,0,0,7,13,1,0,0,8,0,0,0,0,0
0582,Söderköping,9,9,2,0,0,3,1,3,1,0,0,8,8,2,0,0,3,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0583,Motala,18,27,2,0,0,6,1,4,1,0,0,17,24,2,0,0,6,1,4,1,0,0,1,3,0,0,0,0,0,0,0,0,0
0584,Vadstena,1,3,0,0,0,0,0,0,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0586,Mjölby,12,16,4,0,0,4,1,1,1,0,0,12,16,4,0,0,4,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0604,Aneby,5,6,4,0,0,0,0,0,0,0,0,4,5,3,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0
0617,Gnosjö,5,7,1,0,0,1,0,3,1,0,0,5,7,1,0,0,1,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0642,Mullsjö,2,4,1,0,0,0,0,0,0,0,0,2,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0643,Habo,6,7,1,0,0,0,0,0,0,0,0,6,7,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0662,Gislaved,12,17,2,0,0,5,2,2,1,0,0,11,16,2,0,0,4,2,2,1,0,0,1,1,0,0,0,1,0,0,0,0,0
0665,Vaggeryd,9,12,3,0,0,1,0,1,1,0,0,8,11,3,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0680,Jönköping,42,56,11,0,0,28,5,4,3,1,0,39,49,9,0,0,19,3,4,3,1,0,3,7,2,0,0,9,2,0,0,0,0
0682,Nässjö,11,16,2,0,0,3,1,3,1,0,0,11,16,2,0,0,3,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0683,Värnamo,14,21,2,0,0,4,1,3,1,0,0,14,21,2,0,0,4,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0684,Sävsjö,6,7,1,0,0,2,1,3,1,0,0,5,6,1,0,0,2,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0685,Vetlanda,15,18,3,0,0,6,1,5,2,0,0,14,17,3,0,0,6,1,5,2,0,0,1,1,0,0,0,0,0,0,0,0,0
0686,Eksjö,7,13,3,0,0,3,1,3,1,0,0,7,12,2,0,0,3,1,3,1,0,0,0,1,1,0,0,0,0,0,0,0,0
0687,Tranås,8,12,1,0,0,3,1,2,1,0,0,7,11,1,0,0,3,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0760,Uppvidinge,5,7,1,0,0,1,0,2,1,0,0,4,6,1,0,0,1,0,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0761,Lessebo,4,5,1,0,0,1,1,3,1,0,0,4,5,1,0,0,1,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0763,Tingsryd,7,8,8,0,0,2,0,1,1,0,0,6,7,8,0,0,1,0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0
0764,Alvesta,7,8,1,0,0,1,1,1,1,0,0,6,7,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0765,Älmhult,12,17,2,0,0,2,1,3,1,0,0,10,15,2,0,0,2,1,3,1,0,0,2,2,0,0,0,0,0,0,0,0,0
0767,Markaryd,4,7,1,0,0,1,0,3,1,0,0,4,7,1,0,0,1,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0780,Växjö,37,50,3,0,0,21,2,3,1,1,0,33,42,3,0,0,14,2,3,1,1,0,4,8,0,0,0,7,0,0,0,0,0
0781,Ljungby,15,20,2,0,0,5,1,3,1,0,0,13,18,2,0,0,4,1,3,1,0,0,2,2,0,0,0,1,0,0,0,0,0
0821,Högsby,3,4,0,0,0,1,0,1,1,0,0,3,4,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0834,Torsås,5,5,1,0,0,2,0,1,0,0,0,5,5,1,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0840,Mörbylånga,7,10,2,0,0,0,0,0,0,0,0,6,8,1,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0
0860,Hultsfred,6,9,2,0,0,3,1,1,1,0,0,5,8,2,0,0,3,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0861,Mönsterås,6,8,1,0,0,0,0,1,1,0,0,6,8,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0862,Emmaboda,5,6,2,0,0,1,0,3,1,0,0,5,6,2,0,0,1,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0880,Kalmar,21,27,1,0,0,8,1,2,1,1,0,18,21,1,0,0,3,1,2,1,1,0,3,6,0,0,0,5,0,0,0,0,0
0881,Nybro,11,15,2,0,0,3,0,3,1,0,0,10,14,2,0,0,3,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
0882,Oskarshamn,10,11,2,0,0,3,1,3,1,0,0,9,10,2,0,0,2,1,3,1,0,0,1,1,0,0,0,1,0,0,0,0,0
0883,Västervik,16,21,3,0,0,5,1,1,1,0,0,15,19,3,0,0,4,1,1,1,0,0,1,2,0,0,0,1,0,0,0,0,0
0884,Vimmerby,8,10,1,0,0,3,0,2,1,0,0,8,10,1,0,0,3,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0885,Borgholm,5,6,1,0,0,0,0,1,1,0,0,5,6,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
0980,Gotland,33,37,3,0,0,6,1,2,2,0,0,29,33,3,0,0,5,1,2,2,0,0,4,4,0,0,0,1,0,0,0,0,0
1060,Olofström,5,6,2,0,0,3,0,3,1,0,0,5,6,2,0,0,3,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1080,Karlskrona,27,33,1,0,0,5,1,3,1,1,0,20,26,1,0,0,4,1,3,1,1,0,7,7,0,0,0,1,0,0,0,0,0
1081,Ronneby,13,18,2,0,0,5,1,2,1,0,0,11,16,2,0,0,5,1,2,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1082,Karlshamn,11,15,1,0,0,5,1,1,1,0,0,8,11,1,0,0,4,1,1,1,0,0,3,4,0,0,0,1,0,0,0,0,0
1083,Sölvesborg,8,9,1,0,0,3,1,3,1,0,0,8,9,1,0,0,3,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1214,Svalöv,6,9,1,0,0,1,2,3,1,0,0,5,7,1,0,0,1,2,3,1,0,0,1,2,0,0,0,0,0,0,0,0,0
1230,Staffanstorp,10,13,0,0,0,2,1,0,0,0,0,8,11,0,0,0,1,0,0,0,0,0,2,2,0,0,0,1,1,0,0,0,0
1231,Burlöv,7,10,0,0,0,1,0,3,1,0,0,7,10,0,0,0,1,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1233,Vellinge,14,15,1,0,0,1,0,1,1,0,0,9,10,1,0,0,1,0,1,1,0,0,5,5,0,0,0,0,0,0,0,0,0
1256,Östra Göinge,5,9,2,0,0,1,0,2,1,0,0,4,8,1,0,0,1,0,2,1,0,0,1,1,1,0,0,0,0,0,0,0,0
1257,Örkelljunga,6,8,1,0,0,1,0,3,1,0,0,5,7,1,0,0,1,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1260,Bjuv,4,4,2,0,0,1,0,3,1,0,0,4,4,2,0,0,1,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1261,Kävlinge,11,14,2,0,0,1,0,2,1,0,0,9,12,2,0,0,1,0,2,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1262,Lomma,8,9,1,0,0,0,0,1,1,0,1,7,8,1,0,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0
1263,Svedala,6,9,2,0,0,2,0,1,1,0,0,5,8,2,0,0,1,0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1264,Skurup,7,10,1,0,0,1,1,2,1,0,0,7,9,1,0,0,1,1,2,1,0,0,0,1,0,0,0,0,0,0,0,0,0
1265,Sjöbo,8,10,1,0,0,1,0,3,1,0,0,5,6,1,0,0,1,0,3,1,0,0,3,4,0,0,0,0,0,0,0,0,0
1266,Hörby,7,9,1,0,0,2,0,1,1,0,0,6,8,1,0,0,1,0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1267,Höör,8,10,1,0,0,2,0,2,1,0,0,5,7,1,0,0,1,0,2,1,0,0,3,3,0,0,0,1,0,0,0,0,0
1270,Tomelilla,6,7,2,0,0,1,1,0,0,0,0,5,6,2,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1,0,0,0,0
1272,Bromölla,5,7,2,0,0,1,0,1,1,0,0,5,7,2,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1273,Osby,4,6,1,0,0,2,1,3,2,0,0,4,6,1,0,0,2,1,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1275,Perstorp,1,3,0,0,0,2,0,1,1,0,0,1,3,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0
1276,Klippan,6,7,1,0,0,5,1,2,1,0,0,5,6,1,0,0,4,1,2,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1277,Åstorp,6,7,1,0,0,1,0,2,1,0,0,6,7,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1278,Båstad,5,5,0,0,0,2,0,3,1,0,0,4,4,0,0,0,1,0,3,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1280,Malmö,76,103,19,0,0,35,4,28,10,1,0,59,80,17,0,0,13,3,28,10,1,0,17,23,2,0,0,22,1,0,0,0,0
1281,Lund,43,52,7,1,0,19,1,4,1,0,1,33,40,6,1,0,5,1,4,1,0,1,10,12,1,0,0,14,0,0,0,0,0
1282,Landskrona,15,18,1,0,0,2,1,3,2,0,0,11,12,1,0,0,2,1,3,2,0,0,4,6,0,0,0,0,0,0,0,0,0
1283,Helsingborg,52,60,7,0,0,26,4,4,2,0,0,33,34,6,0,0,7,4,4,2,0,0,19,26,1,0,0,19,0,0,0,0,0
1284,Höganäs,9,10,1,0,0,1,0,3,2,0,0,6,7,1,0,0,1,0,3,2,0,0,3,3,0,0,0,0,0,0,0,0,0
1285,Eslöv,11,16,1,0,0,1,1,3,1,0,0,10,15,1,0,0,1,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1286,Ystad,12,14,1,0,0,7,1,2,2,0,0,9,10,1,0,0,5,1,2,2,0,0,3,4,0,0,0,2,0,0,0,0,0
1287,Trelleborg,14,17,2,0,0,1,1,3,1,0,0,12,14,2,0,0,1,1,3,1,0,0,2,3,0,0,0,0,0,0,0,0,0
1290,Kristianstad,39,57,7,0,0,19,2,5,1,1,0,33,51,7,0,0,11,2,5,1,1,0,6,6,0,0,0,8,0,0,0,0,0
1291,Simrishamn,7,10,1,0,0,1,1,1,1,0,0,4,6,1,0,0,1,1,1,1,0,0,3,4,0,0,0,0,0,0,0,0,0
1292,Ängelholm,10,22,2,0,0,5,2,3,2,0,0,10,22,2,0,0,5,2,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1293,Hässleholm,25,28,1,0,0,3,1,4,1,0,0,23,26,1,0,0,3,1,4,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1315,Hylte,6,9,1,0,0,2,1,2,1,0,0,6,8,1,0,0,1,1,2,1,0,0,0,1,0,0,0,1,0,0,0,0,0
1380,Halmstad,31,51,5,0,0,22,2,2,2,1,0,28,47,5,0,0,16,2,2,2,1,0,3,4,0,0,0,6,0,0,0,0,0
1381,Laholm,14,18,1,0,0,1,1,3,1,0,0,11,15,1,0,0,1,1,3,1,0,0,3,3,0,0,0,0,0,0,0,0,0
1382,Falkenberg,21,24,2,0,0,8,1,1,1,0,0,18,21,2,0,0,7,1,1,1,0,0,3,3,0,0,0,1,0,0,0,0,0
1383,Varberg,22,37,2,0,0,6,1,2,1,0,0,20,34,2,0,0,3,1,2,1,0,0,2,3,0,0,0,3,0,0,0,0,0
1384,Kungsbacka,28,60,3,0,0,14,2,3,1,0,0,21,52,2,0,0,10,2,3,1,0,0,7,8,1,0,0,4,0,0,0,0,0
1401,Härryda,14,28,4,0,0,7,0,4,2,0,0,13,27,4,0,0,6,0,4,2,0,0,1,1,0,0,0,1,0,0,0,0,0
1402,Partille,10,16,1,0,0,1,1,3,1,0,0,9,15,1,0,0,1,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1407,Öckerö,6,11,1,0,0,1,0,2,0,0,0,5,10,1,0,0,1,0,2,0,0,0,1,1,0,0,0,0,0,0,0,0,0
1415,Stenungsund,9,15,4,0,0,5,1,2,2,0,0,8,14,4,0,0,5,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0
1419,Tjörn,6,9,2,0,0,0,0,1,0,0,0,5,8,2,0,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0
1421,Orust,7,10,1,0,0,1,0,1,1,0,0,4,7,1,0,0,1,0,1,1,0,0,3,3,0,0,0,0,0,0,0,0,0
1427,Sotenäs,5,6,1,0,0,1,0,2,2,0,0,5,6,1,0,0,1,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1430,Munkedal,4,6,2,0,0,4,1,2,1,0,0,4,6,2,0,0,2,1,2,1,0,0,0,0,0,0,0,2,0,0,0,0,0
1435,Tanum,7,8,1,0,0,1,1,2,1,0,0,7,8,1,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1438,Dals-Ed,1,2,2,0,0,1,1,3,1,0,0,1,2,2,0,0,1,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1439,Färgelanda,5,7,1,0,0,0,0,1,1,0,0,3,5,1,0,0,0,0,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1440,Ale,9,15,2,0,0,2,0,2,1,0,0,8,14,2,0,0,1,0,2,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1441,Lerum,16,34,3,0,0,5,1,3,1,0,0,14,32,3,0,0,5,1,3,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1442,Vårgårda,6,7,1,0,0,1,0,2,1,0,0,6,7,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1443,Bollebygd,4,6,1,0,0,1,0,0,0,0,0,3,5,1,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0
1444,Grästorp,1,2,2,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1445,Essunga,3,4,1,0,0,0,1,3,0,0,0,3,4,1,0,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1446,Karlsborg,3,4,1,0,0,1,0,1,1,0,0,2,3,1,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1447,Gullspång,2,3,1,0,0,0,0,1,1,0,0,2,3,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1452,Tranemo,5,7,5,0,0,1,1,2,1,0,0,5,7,5,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1460,Bengtsfors,3,4,2,0,0,1,0,2,1,0,0,3,4,2,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1461,Mellerud,4,6,1,0,0,1,0,3,2,0,0,4,6,1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1462,Lilla Edet,5,6,2,0,0,0,1,1,1,0,0,4,5,1,0,0,0,0,1,1,0,0,1,1,1,0,0,0,1,0,0,0,0
1463,Mark,15,23,3,0,0,7,1,1,1,0,0,13,21,2,0,0,6,1,1,1,0,0,2,2,1,0,0,1,0,0,0,0,0
1465,Svenljunga,7,9,1,0,0,2,0,3,1,0,0,6,8,1,0,0,2,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1466,Herrljunga,7,10,2,0,0,1,0,0,0,0,0,7,10,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1470,Vara,8,12,1,0,0,3,0,4,1,0,0,6,9,1,0,0,2,0,4,1,0,0,2,3,0,0,0,1,0,0,0,0,0
1471,Götene,5,7,0,0,0,2,0,1,0,0,0,5,7,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0
1472,Tibro,3,4,2,0,0,2,0,0,0,0,0,3,4,2,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
1473,Töreboda,4,6,2,0,0,2,2,2,1,0,0,3,5,2,0,0,2,2,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1480,Göteborg,136,179,45,0,0,81,10,28,19,0,2,105,132,41,0,0,44,9,28,19,0,2,31,47,4,0,0,37,1,0,0,0,0
1481,Mölndal,18,24,2,0,0,4,1,4,2,0,0,16,22,2,0,0,4,1,4,2,0,0,2,2,0,0,0,0,0,0,0,0,0
1482,Kungälv,16,23,2,0,0,5,1,1,1,0,0,12,19,2,0,0,5,1,1,1,0,0,4,4,0,0,0,0,0,0,0,0,0
1484,Lysekil,6,7,1,0,0,2,1,1,1,0,0,6,7,1,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1485,Uddevalla,16,23,3,0,0,24,2,5,2,0,0,13,20,3,0,0,22,2,5,2,0,0,3,3,0,0,0,2,0,0,0,0,0
1486,Strömstad,8,9,1,0,0,2,0,3,1,0,0,8,9,1,0,0,2,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1487,Vänersborg,17,32,2,1,0,4,1,5,2,0,0,15,30,2,1,0,2,0,5,2,0,0,2,2,0,0,0,2,1,0,0,0,0
1488,Trollhättan,19,33,8,0,0,9,1,4,1,1,0,15,28,8,0,0,4,1,4,1,1,0,4,5,0,0,0,5,0,0,0,0,0
1489,Alingsås,16,21,2,0,0,6,1,3,1,0,0,14,19,2,0,0,5,1,3,1,0,0,2,2,0,0,0,1,0,0,0,0,0
1490,Borås,36,48,4,0,0,23,3,6,1,1,0,33,44,4,0,0,18,3,6,1,1,0,3,4,0,0,0,5,0,0,0,0,0
1491,Ulricehamn,12,15,1,0,0,2,1,3,1,0,0,10,13,1,0,0,2,1,3,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1492,Åmål,3,5,4,0,0,3,1,3,1,0,0,2,4,4,0,0,3,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1493,Mariestad,11,14,1,0,0,4,1,1,1,0,0,9,11,1,0,0,3,1,1,1,0,0,2,3,0,0,0,1,0,0,0,0,0
1494,Lidköping,17,22,3,0,0,6,1,5,2,0,0,16,20,3,0,0,6,1,5,2,0,0,1,2,0,0,0,0,0,0,0,0,0
1495,Skara,7,8,2,0,0,6,1,5,1,0,1,6,7,1,0,0,5,0,5,1,0,1,1,1,1,0,0,1,1,0,0,0,0
1496,Skövde,19,25,3,0,0,13,2,3,1,1,0,17,23,3,0,0,6,2,3,1,1,0,2,2,0,0,0,7,0,0,0,0,0
1497,Hjo,5,6,2,0,0,1,0,3,2,0,0,5,6,2,0,0,1,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1498,Tidaholm,5,9,2,0,0,2,0,3,1,0,0,5,9,2,0,0,2,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1499,Falköping,14,21,4,0,0,4,1,2,1,0,0,13,20,4,0,0,4,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1715,Kil,5,7,1,0,0,1,0,2,1,0,0,5,7,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1730,Eda,4,4,1,0,0,0,0,1,1,0,0,4,4,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1737,Torsby,5,6,3,0,0,1,1,1,1,0,0,5,6,3,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1760,Storfors,2,4,1,0,0,1,0,1,1,0,0,2,3,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0
1761,Hammarö,5,11,1,0,0,0,0,0,0,0,0,5,11,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1762,Munkfors,1,2,1,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1763,Forshaga,5,7,6,0,0,1,0,1,1,0,0,5,7,6,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0
1764,Grums,4,5,2,0,0,1,0,1,0,0,0,2,3,2,0,0,1,0,1,0,0,0,2,2,0,0,0,0,0,0,0,0,0
1765,Årjäng,5,7,1,0,0,1,1,3,1,0,0,4,6,1,0,0,1,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1766,Sunne,7,8,3,0,0,2,1,3,1,0,0,6,7,3,0,0,2,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1780,Karlstad,23,41,6,0,0,22,3,6,2,0,1,20,36,5,0,0,13,3,6,2,0,1,3,5,1,0,0,9,0,0,0,0,0
1781,Kristinehamn,7,13,1,0,0,3,1,3,1,0,0,7,13,1,0,0,3,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1782,Filipstad,7,8,3,0,0,1,0,1,1,0,0,6,7,3,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1783,Hagfors,4,7,1,0,0,2,1,3,1,0,0,4,7,1,0,0,2,1,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1784,Arvika,11,15,3,0,0,3,1,2,1,0,0,11,14,3,0,0,2,1,2,1,0,0,0,1,0,0,0,1,0,0,0,0,0
1785,Säffle,8,9,3,0,0,1,2,1,1,0,0,6,7,3,0,0,1,2,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1814,Lekeberg,3,4,1,0,0,1,0,2,1,0,0,3,4,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1860,Laxå,2,3,1,0,0,0,0,0,0,0,0,2,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1861,Hallsberg,6,7,0,0,0,5,1,2,1,0,0,6,7,0,0,0,5,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1862,Degerfors,4,5,2,0,0,1,0,1,1,0,0,4,5,2,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1863,Hällefors,2,4,1,0,0,1,0,1,1,0,0,2,4,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1864,Ljusnarsberg,1,2,1,0,0,0,0,1,1,0,0,1,2,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1880,Örebro,53,68,6,3,0,36,3,18,2,0,1,45,53,6,3,0,25,2,18,2,0,1,8,15,0,0,0,11,1,0,0,0,0
1881,Kumla,8,11,2,0,0,1,1,4,2,0,0,8,11,2,0,0,1,1,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0
1882,Askersund,5,6,1,0,0,0,0,0,0,0,0,5,6,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1883,Karlskoga,7,12,1,0,0,2,1,3,1,0,0,6,11,1,0,0,1,1,3,1,0,0,1,1,0,0,0,1,0,0,0,0,0
1884,Nora,6,7,2,0,0,1,0,3,1,0,0,5,6,2,0,0,1,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1885,Lindesberg,8,11,1,0,0,4,1,3,1,0,0,6,9,1,0,0,4,1,3,1,0,0,2,2,0,0,0,0,0,0,0,0,0
1904,Skinnskatteberg,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1907,Surahammar,4,6,1,0,0,2,0,1,0,0,0,4,6,1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0
1960,Kungsör,3,4,1,0,0,1,0,1,1,0,0,3,4,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1961,Hallstahammar,5,7,2,0,0,2,0,1,1,0,0,5,7,2,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0
1962,Norberg,1,2,1,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1980,Västerås,49,60,12,0,0,21,5,10,4,1,0,38,42,11,0,0,7,4,10,4,1,0,11,18,1,0,0,14,1,0,0,0,0
1981,Sala,11,14,2,0,0,2,1,1,1,0,0,11,14,2,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1982,Fagersta,4,5,1,0,0,1,2,3,1,0,0,3,4,1,0,0,1,2,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
1983,Köping,7,12,3,0,0,4,2,2,1,0,0,7,12,3,0,0,4,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
1984,Arboga,6,8,1,0,0,1,0,3,1,0,0,5,7,1,0,0,1,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2021,Vansbro,4,6,5,0,0,1,0,1,1,0,0,3,5,5,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2023,Malung-Sälen,5,7,4,0,0,1,0,1,1,0,0,5,7,4,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2026,Gagnef,6,7,1,0,0,1,0,2,1,0,0,6,7,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2029,Leksand,9,10,1,0,0,1,1,1,1,0,0,7,8,1,0,0,1,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0
2031,Rättvik,7,8,2,0,0,1,1,0,0,0,0,7,8,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2034,Orsa,5,5,1,0,0,0,0,0,0,0,0,4,4,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0
2039,Älvdalen,4,4,0,0,0,1,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0
2061,Smedjebacken,4,6,0,0,0,1,0,0,0,0,0,4,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
2062,Mora,12,14,1,0,0,2,1,3,1,0,0,11,13,1,0,0,2,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2080,Falun,23,26,3,0,0,7,1,1,1,1,0,21,23,3,0,0,3,1,1,1,1,0,2,3,0,0,0,4,0,0,0,0,0
2081,Borlänge,15,20,1,0,0,7,1,3,1,1,0,14,17,1,0,0,4,1,3,1,1,0,1,3,0,0,0,3,0,0,0,0,0
2082,Säter,3,4,2,0,0,1,0,1,1,0,0,3,4,2,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2083,Hedemora,8,10,3,0,0,1,3,3,1,0,0,6,7,2,0,0,1,2,3,1,0,0,2,3,1,0,0,0,1,0,0,0,0
2084,Avesta,9,12,2,0,0,1,1,3,1,0,0,8,11,2,0,0,1,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2085,Ludvika,11,13,2,0,0,4,1,3,1,0,0,10,12,2,0,0,3,1,3,1,0,0,1,1,0,0,0,1,0,0,0,0,0
2101,Ockelbo,2,4,0,0,0,0,0,1,1,0,0,2,4,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2104,Hofors,3,4,1,0,0,1,0,2,1,0,0,3,4,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2121,Ovanåker,7,9,0,0,0,2,0,3,1,0,0,7,9,0,0,0,2,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2132,Nordanstig,7,7,1,0,0,1,0,1,1,0,0,5,5,1,0,0,1,0,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0
2161,Ljusdal,8,10,1,0,0,3,0,3,1,0,0,6,7,1,0,0,1,0,3,1,0,0,2,3,0,0,0,2,0,0,0,0,0
2180,Gävle,29,36,7,0,0,10,1,3,1,1,0,25,29,7,0,0,4,1,3,1,1,0,4,7,0,0,0,6,0,0,0,0,0
2181,Sandviken,12,15,2,0,0,3,1,3,1,0,0,11,14,2,0,0,2,1,3,1,0,0,1,1,0,0,0,1,0,0,0,0,0
2182,Söderhamn,12,17,1,0,0,2,0,2,1,0,0,11,15,1,0,0,2,0,2,1,0,0,1,2,0,0,0,0,0,0,0,0,0
2183,Bollnäs,12,15,2,0,0,6,1,2,1,0,0,7,9,2,0,0,2,1,2,1,0,0,5,6,0,0,0,4,0,0,0,0,0
2184,Hudiksvall,19,24,2,0,0,7,1,3,1,0,0,16,20,1,0,0,6,1,3,1,0,0,3,4,1,0,0,1,0,0,0,0,0
2260,Ånge,5,6,2,0,0,1,0,3,1,0,0,4,5,2,0,0,1,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2262,Timrå,7,9,2,0,0,2,0,4,1,0,0,7,9,2,0,0,2,0,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2280,Härnösand,9,14,1,1,0,3,1,1,1,0,0,8,13,1,1,0,3,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2281,Sundsvall,31,40,6,0,0,13,1,12,6,1,0,24,29,6,0,0,7,1,12,6,1,0,7,11,0,0,0,6,0,0,0,0,0
2282,Kramfors,8,10,1,0,0,1,1,2,1,0,0,7,9,1,0,0,1,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2283,Sollefteå,12,13,1,0,0,1,1,1,1,0,0,12,13,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2284,Örnsköldsvik,30,35,1,0,0,13,1,6,1,0,0,27,31,1,0,0,10,1,6,1,0,0,3,4,0,0,0,3,0,0,0,0,0
2303,Ragunda,2,3,3,0,0,1,0,1,1,0,0,2,3,3,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2305,Bräcke,3,3,0,0,0,1,0,1,1,0,0,3,3,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2309,Krokom,14,16,1,0,0,3,1,3,1,0,0,14,16,1,0,0,2,1,3,1,0,0,0,0,0,0,0,1,0,0,0,0,0
2313,Strömsund,8,9,0,0,0,1,0,1,1,0,0,8,9,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2321,Åre,7,7,3,0,0,2,0,3,1,0,0,7,7,3,0,0,2,0,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2326,Berg,8,10,1,0,0,1,0,1,1,0,0,7,9,1,0,0,1,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2361,Härjedalen,8,9,0,0,0,1,0,1,1,0,0,8,9,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2380,Östersund,25,29,1,0,0,14,1,3,1,1,0,20,24,1,0,0,12,1,3,1,1,0,5,5,0,0,0,2,0,0,0,0,0
2401,Nordmaling,3,5,1,0,0,1,0,1,1,0,0,3,5,1,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2403,Bjurholm,1,1,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2404,Vindeln,4,5,2,0,0,0,0,2,1,0,0,4,5,2,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2409,Robertsfors,5,7,1,0,0,0,0,1,1,0,0,5,7,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2417,Norsjö,3,2,1,0,0,1,1,2,1,0,0,3,2,1,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2418,Malå,1,1,0,0,0,1,0,2,1,0,0,1,1,0,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2421,Storuman,5,6,0,0,0,2,0,1,1,0,0,5,6,0,0,0,2,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2422,Sorsele,3,3,1,0,0,0,0,2,1,0,0,3,3,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2425,Dorotea,2,2,1,0,0,0,0,1,1,0,0,2,2,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2460,Vännäs,3,7,1,0,0,4,0,4,1,0,0,2,6,1,0,0,4,0,4,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2462,Vilhelmina,4,7,2,0,0,2,0,3,1,0,0,3,6,1,0,0,2,0,3,1,0,0,1,1,1,0,0,0,0,0,0,0,0
2463,Åsele,2,2,0,0,0,0,0,2,1,0,0,2,2,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2480,Umeå,50,64,4,1,0,14,3,4,1,0,2,43,56,4,1,0,10,3,4,1,0,2,7,8,0,0,0,4,0,0,0,0,0
2481,Lycksele,9,12,1,0,0,4,1,1,1,0,0,9,12,1,0,0,4,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2482,Skellefteå,34,38,7,0,0,10,2,4,1,0,0,29,32,7,0,0,7,2,4,1,0,0,5,6,0,0,0,3,0,0,0,0,0
2505,Arvidsjaur,2,4,2,0,0,1,1,2,1,0,0,2,4,2,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2506,Arjeplog,1,1,1,0,0,1,0,2,1,0,0,1,1,1,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2510,Jokkmokk,3,4,2,0,1,1,1,3,1,0,0,3,3,2,0,1,1,1,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0
2513,Överkalix,2,2,1,0,0,1,0,2,1,0,0,1,1,1,0,0,1,0,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2514,Kalix,9,10,2,0,0,2,1,2,2,0,0,8,9,2,0,0,2,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0
2518,Övertorneå,3,4,0,0,0,1,1,1,1,0,0,2,3,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2521,Pajala,5,6,2,0,0,1,1,3,1,0,0,4,5,2,0,0,1,1,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2523,Gällivare,9,11,2,0,1,3,1,3,2,0,0,9,10,2,0,1,3,1,3,2,0,0,0,1,0,0,0,0,0,0,0,0,0
2560,Älvsbyn,3,5,1,0,0,1,1,1,1,0,0,3,5,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0
2580,Luleå,32,48,2,0,0,13,1,3,1,0,0,27,43,2,0,0,10,1,3,1,0,0,5,5,0,0,0,3,0,0,0,0,0
2581,Piteå,20,29,1,0,0,6,1,3,1,0,0,17,26,1,0,0,6,1,3,1,0,0,3,3,0,0,0,0,0,0,0,0,0
2582,Boden,13,15,3,0,0,5,1,1,1,0,0,9,11,3,0,0,5,1,1,1,0,0,4,4,0,0,0,0,0,0,0,0,0
2583,Haparanda,5,6,2,0,0,1,0,3,1,0,0,4,5,2,0,0,1,0,3,1,0,0,1,1,0,0,0,0,0,0,0,0,0
2584,Kiruna,13,14,2,0,2,4,1,3,1,0,0,12,12,2,0,2,3,1,3,1,0,0,1,2,0,0,0,1,0,0,0,0,0
1 code municipality forskoleklass_n_total grundskola_n_total anpassad_grundskola_n_total specialskola_n_total sameskola_n_total gymnasieskola_n_total anpassad_gymnasieskola_n_total komvux_n_total sfi_n_total university_college_n_total university_n_total forskoleklass_n_public grundskola_n_public anpassad_grundskola_n_public specialskola_n_public sameskola_n_public gymnasieskola_n_public anpassad_gymnasieskola_n_public komvux_n_public sfi_n_public university_college_n_public university_n_public forskoleklass_n_private grundskola_n_private anpassad_grundskola_n_private specialskola_n_private sameskola_n_private gymnasieskola_n_private anpassad_gymnasieskola_n_private komvux_n_private sfi_n_private university_college_n_private university_n_private
2 0114 Upplands Väsby 14 17 2 0 0 2 0 4 2 0 0 5 7 2 0 0 1 0 4 2 0 0 9 10 0 0 0 1 0 0 0 0 0
3 0115 Vallentuna 11 13 3 0 0 1 1 0 0 0 0 8 8 1 0 0 1 0 0 0 0 0 3 5 2 0 0 0 1 0 0 0 0
4 0117 Österåker 16 18 3 0 0 2 0 3 2 0 0 10 12 3 0 0 1 0 3 2 0 0 6 6 0 0 0 1 0 0 0 0 0
5 0120 Värmdö 17 18 1 0 0 4 1 2 2 0 0 12 13 1 0 0 2 1 2 2 0 0 5 5 0 0 0 2 0 0 0 0 0
6 0123 Järfälla 19 25 8 0 0 3 1 2 1 0 0 17 22 8 0 0 2 1 2 1 0 0 2 3 0 0 0 1 0 0 0 0 0
7 0125 Ekerö 12 14 1 0 0 1 1 1 0 0 0 9 11 1 0 0 1 1 1 0 0 0 3 3 0 0 0 0 0 0 0 0 0
8 0126 Huddinge 30 37 6 0 0 7 2 4 3 1 0 26 30 6 0 0 5 2 4 3 1 0 4 7 0 0 0 2 0 0 0 0 0
9 0127 Botkyrka 24 27 9 0 0 5 2 2 1 0 0 19 21 9 0 0 4 1 2 1 0 0 5 6 0 0 0 1 1 0 0 0 0
10 0128 Salem 7 7 1 0 0 1 0 1 1 0 0 4 4 1 0 0 1 0 1 1 0 0 3 3 0 0 0 0 0 0 0 0 0
11 0136 Haninge 28 31 6 0 0 5 3 1 1 0 0 18 19 6 0 0 3 2 1 1 0 0 10 12 0 0 0 2 1 0 0 0 0
12 0138 Tyresö 13 16 2 0 0 1 1 3 1 0 0 11 13 2 0 0 1 1 3 1 0 0 2 3 0 0 0 0 0 0 0 0 0
13 0139 Upplands-Bro 11 14 1 0 0 1 1 3 1 0 0 8 10 1 0 0 1 1 3 1 0 0 3 4 0 0 0 0 0 0 0 0 0
14 0140 Nykvarn 3 4 2 0 0 1 0 0 0 0 0 3 4 2 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
15 0160 Täby 20 32 4 0 0 8 1 4 2 0 0 13 18 2 0 0 2 1 4 2 0 0 7 14 2 0 0 6 0 0 0 0 0
16 0162 Danderyd 12 16 3 0 0 4 2 0 0 0 0 8 10 2 0 0 1 1 0 0 0 0 4 6 1 0 0 3 1 0 0 0 0
17 0163 Sollentuna 30 31 4 0 0 14 2 2 1 0 0 15 17 2 0 0 8 0 2 1 0 0 15 14 2 0 0 6 2 0 0 0 0
18 0180 Stockholm 206 247 54 3 0 96 12 17 15 11 2 136 142 42 3 0 31 6 17 15 11 2 70 105 12 0 0 65 6 0 0 0 0
19 0181 Södertälje 30 34 10 0 0 11 4 2 1 0 0 19 21 5 0 0 3 1 2 1 0 0 11 13 5 0 0 8 3 0 0 0 0
20 0182 Nacka 33 38 5 0 0 14 3 1 1 0 0 19 22 4 0 0 2 3 1 1 0 0 14 16 1 0 0 12 0 0 0 0 0
21 0183 Sundbyberg 9 12 1 0 0 3 0 2 1 0 0 7 7 1 0 0 1 0 2 1 0 0 2 5 0 0 0 2 0 0 0 0 0
22 0184 Solna 16 21 5 0 0 9 6 2 2 0 1 9 10 1 0 0 1 2 2 2 0 1 7 11 4 0 0 8 4 0 0 0 0
23 0186 Lidingö 16 18 1 0 0 3 0 3 2 0 0 11 12 1 0 0 1 0 3 2 0 0 5 6 0 0 0 2 0 0 0 0 0
24 0187 Vaxholm 4 5 0 0 0 0 0 0 0 0 0 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
25 0188 Norrtälje 29 34 2 0 0 4 2 2 0 0 0 20 23 1 0 0 1 1 2 0 0 0 9 11 1 0 0 3 1 0 0 0 0
26 0191 Sigtuna 16 20 3 0 0 8 1 4 2 0 0 13 15 3 0 0 3 1 3 2 0 0 3 5 0 0 0 5 0 1 0 0 0
27 0192 Nynäshamn 6 6 2 0 0 1 2 1 1 0 0 5 5 2 0 0 1 2 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
28 0305 Håbo 8 8 1 0 0 2 1 1 1 0 0 7 6 1 0 0 2 1 1 1 0 0 1 2 0 0 0 0 0 0 0 0 0
29 0319 Älvkarleby 4 5 1 0 0 1 0 1 1 0 0 3 4 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
30 0330 Knivsta 9 11 1 0 0 1 0 1 1 0 0 7 9 1 0 0 1 0 1 1 0 0 2 2 0 0 0 0 0 0 0 0 0
31 0331 Heby 7 9 1 0 0 0 0 3 1 0 0 6 8 1 0 0 0 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
32 0360 Tierp 11 12 1 0 0 1 1 3 1 0 0 11 12 1 0 0 1 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
33 0380 Uppsala 59 77 8 0 0 25 5 10 5 1 2 49 57 5 0 0 8 2 10 5 1 2 10 20 3 0 0 17 3 0 0 0 0
34 0381 Enköping 14 17 2 0 0 1 1 1 1 0 0 11 12 2 0 0 1 1 1 1 0 0 3 5 0 0 0 0 0 0 0 0 0
35 0382 Östhammar 7 9 1 0 0 3 0 3 1 0 0 7 9 1 0 0 1 0 3 1 0 0 0 0 0 0 0 2 0 0 0 0 0
36 0428 Vingåker 5 7 2 0 0 1 1 1 1 0 0 4 6 2 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
37 0461 Gnesta 5 5 1 0 0 0 0 1 1 0 0 4 4 1 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
38 0480 Nyköping 28 34 3 0 0 10 3 4 1 0 0 22 24 3 0 0 4 2 4 1 0 0 6 10 0 0 0 6 1 0 0 0 0
39 0481 Oxelösund 2 3 1 0 0 0 0 2 1 0 0 2 3 1 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
40 0482 Flen 8 8 1 0 0 1 1 3 1 0 0 5 5 1 0 0 1 1 3 1 0 0 3 3 0 0 0 0 0 0 0 0 0
41 0483 Katrineholm 10 13 4 0 0 5 1 1 1 0 0 10 12 4 0 0 5 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0
42 0484 Eskilstuna 31 33 7 0 0 12 2 3 1 1 0 27 27 7 0 0 7 2 3 1 1 0 4 6 0 0 0 5 0 0 0 0 0
43 0486 Strängnäs 10 14 2 0 0 2 1 3 1 0 0 6 8 2 0 0 1 1 3 1 0 0 4 6 0 0 0 1 0 0 0 0 0
44 0488 Trosa 4 6 3 0 0 1 1 1 1 0 0 4 6 3 0 0 1 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0
45 0509 Ödeshög 2 3 0 0 0 0 0 0 0 0 0 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
46 0512 Ydre 2 3 0 0 0 0 0 0 0 0 0 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
47 0513 Kinda 3 6 2 0 0 0 0 1 1 0 0 3 6 2 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
48 0560 Boxholm 2 2 2 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
49 0561 Åtvidaberg 3 5 1 0 0 1 0 1 1 0 0 3 5 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
50 0562 Finspång 11 13 1 0 0 2 2 1 1 0 0 10 12 1 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 0 0 0 0
51 0563 Valdemarsvik 4 5 0 0 0 0 0 0 0 0 0 3 4 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
52 0580 Linköping 48 80 8 0 0 28 4 11 4 0 1 42 68 7 0 0 20 4 11 4 0 1 6 12 1 0 0 8 0 0 0 0 0
53 0581 Norrköping 40 65 10 0 0 29 6 9 4 0 0 33 52 9 0 0 21 6 9 4 0 0 7 13 1 0 0 8 0 0 0 0 0
54 0582 Söderköping 9 9 2 0 0 3 1 3 1 0 0 8 8 2 0 0 3 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
55 0583 Motala 18 27 2 0 0 6 1 4 1 0 0 17 24 2 0 0 6 1 4 1 0 0 1 3 0 0 0 0 0 0 0 0 0
56 0584 Vadstena 1 3 0 0 0 0 0 0 0 0 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
57 0586 Mjölby 12 16 4 0 0 4 1 1 1 0 0 12 16 4 0 0 4 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
58 0604 Aneby 5 6 4 0 0 0 0 0 0 0 0 4 5 3 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
59 0617 Gnosjö 5 7 1 0 0 1 0 3 1 0 0 5 7 1 0 0 1 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
60 0642 Mullsjö 2 4 1 0 0 0 0 0 0 0 0 2 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
61 0643 Habo 6 7 1 0 0 0 0 0 0 0 0 6 7 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
62 0662 Gislaved 12 17 2 0 0 5 2 2 1 0 0 11 16 2 0 0 4 2 2 1 0 0 1 1 0 0 0 1 0 0 0 0 0
63 0665 Vaggeryd 9 12 3 0 0 1 0 1 1 0 0 8 11 3 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
64 0680 Jönköping 42 56 11 0 0 28 5 4 3 1 0 39 49 9 0 0 19 3 4 3 1 0 3 7 2 0 0 9 2 0 0 0 0
65 0682 Nässjö 11 16 2 0 0 3 1 3 1 0 0 11 16 2 0 0 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
66 0683 Värnamo 14 21 2 0 0 4 1 3 1 0 0 14 21 2 0 0 4 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
67 0684 Sävsjö 6 7 1 0 0 2 1 3 1 0 0 5 6 1 0 0 2 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
68 0685 Vetlanda 15 18 3 0 0 6 1 5 2 0 0 14 17 3 0 0 6 1 5 2 0 0 1 1 0 0 0 0 0 0 0 0 0
69 0686 Eksjö 7 13 3 0 0 3 1 3 1 0 0 7 12 2 0 0 3 1 3 1 0 0 0 1 1 0 0 0 0 0 0 0 0
70 0687 Tranås 8 12 1 0 0 3 1 2 1 0 0 7 11 1 0 0 3 1 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
71 0760 Uppvidinge 5 7 1 0 0 1 0 2 1 0 0 4 6 1 0 0 1 0 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
72 0761 Lessebo 4 5 1 0 0 1 1 3 1 0 0 4 5 1 0 0 1 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
73 0763 Tingsryd 7 8 8 0 0 2 0 1 1 0 0 6 7 8 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0
74 0764 Alvesta 7 8 1 0 0 1 1 1 1 0 0 6 7 1 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
75 0765 Älmhult 12 17 2 0 0 2 1 3 1 0 0 10 15 2 0 0 2 1 3 1 0 0 2 2 0 0 0 0 0 0 0 0 0
76 0767 Markaryd 4 7 1 0 0 1 0 3 1 0 0 4 7 1 0 0 1 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
77 0780 Växjö 37 50 3 0 0 21 2 3 1 1 0 33 42 3 0 0 14 2 3 1 1 0 4 8 0 0 0 7 0 0 0 0 0
78 0781 Ljungby 15 20 2 0 0 5 1 3 1 0 0 13 18 2 0 0 4 1 3 1 0 0 2 2 0 0 0 1 0 0 0 0 0
79 0821 Högsby 3 4 0 0 0 1 0 1 1 0 0 3 4 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
80 0834 Torsås 5 5 1 0 0 2 0 1 0 0 0 5 5 1 0 0 2 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
81 0840 Mörbylånga 7 10 2 0 0 0 0 0 0 0 0 6 8 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0
82 0860 Hultsfred 6 9 2 0 0 3 1 1 1 0 0 5 8 2 0 0 3 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
83 0861 Mönsterås 6 8 1 0 0 0 0 1 1 0 0 6 8 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
84 0862 Emmaboda 5 6 2 0 0 1 0 3 1 0 0 5 6 2 0 0 1 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
85 0880 Kalmar 21 27 1 0 0 8 1 2 1 1 0 18 21 1 0 0 3 1 2 1 1 0 3 6 0 0 0 5 0 0 0 0 0
86 0881 Nybro 11 15 2 0 0 3 0 3 1 0 0 10 14 2 0 0 3 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
87 0882 Oskarshamn 10 11 2 0 0 3 1 3 1 0 0 9 10 2 0 0 2 1 3 1 0 0 1 1 0 0 0 1 0 0 0 0 0
88 0883 Västervik 16 21 3 0 0 5 1 1 1 0 0 15 19 3 0 0 4 1 1 1 0 0 1 2 0 0 0 1 0 0 0 0 0
89 0884 Vimmerby 8 10 1 0 0 3 0 2 1 0 0 8 10 1 0 0 3 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
90 0885 Borgholm 5 6 1 0 0 0 0 1 1 0 0 5 6 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
91 0980 Gotland 33 37 3 0 0 6 1 2 2 0 0 29 33 3 0 0 5 1 2 2 0 0 4 4 0 0 0 1 0 0 0 0 0
92 1060 Olofström 5 6 2 0 0 3 0 3 1 0 0 5 6 2 0 0 3 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
93 1080 Karlskrona 27 33 1 0 0 5 1 3 1 1 0 20 26 1 0 0 4 1 3 1 1 0 7 7 0 0 0 1 0 0 0 0 0
94 1081 Ronneby 13 18 2 0 0 5 1 2 1 0 0 11 16 2 0 0 5 1 2 1 0 0 2 2 0 0 0 0 0 0 0 0 0
95 1082 Karlshamn 11 15 1 0 0 5 1 1 1 0 0 8 11 1 0 0 4 1 1 1 0 0 3 4 0 0 0 1 0 0 0 0 0
96 1083 Sölvesborg 8 9 1 0 0 3 1 3 1 0 0 8 9 1 0 0 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
97 1214 Svalöv 6 9 1 0 0 1 2 3 1 0 0 5 7 1 0 0 1 2 3 1 0 0 1 2 0 0 0 0 0 0 0 0 0
98 1230 Staffanstorp 10 13 0 0 0 2 1 0 0 0 0 8 11 0 0 0 1 0 0 0 0 0 2 2 0 0 0 1 1 0 0 0 0
99 1231 Burlöv 7 10 0 0 0 1 0 3 1 0 0 7 10 0 0 0 1 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
100 1233 Vellinge 14 15 1 0 0 1 0 1 1 0 0 9 10 1 0 0 1 0 1 1 0 0 5 5 0 0 0 0 0 0 0 0 0
101 1256 Östra Göinge 5 9 2 0 0 1 0 2 1 0 0 4 8 1 0 0 1 0 2 1 0 0 1 1 1 0 0 0 0 0 0 0 0
102 1257 Örkelljunga 6 8 1 0 0 1 0 3 1 0 0 5 7 1 0 0 1 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
103 1260 Bjuv 4 4 2 0 0 1 0 3 1 0 0 4 4 2 0 0 1 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
104 1261 Kävlinge 11 14 2 0 0 1 0 2 1 0 0 9 12 2 0 0 1 0 2 1 0 0 2 2 0 0 0 0 0 0 0 0 0
105 1262 Lomma 8 9 1 0 0 0 0 1 1 0 1 7 8 1 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 0
106 1263 Svedala 6 9 2 0 0 2 0 1 1 0 0 5 8 2 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0
107 1264 Skurup 7 10 1 0 0 1 1 2 1 0 0 7 9 1 0 0 1 1 2 1 0 0 0 1 0 0 0 0 0 0 0 0 0
108 1265 Sjöbo 8 10 1 0 0 1 0 3 1 0 0 5 6 1 0 0 1 0 3 1 0 0 3 4 0 0 0 0 0 0 0 0 0
109 1266 Hörby 7 9 1 0 0 2 0 1 1 0 0 6 8 1 0 0 1 0 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0
110 1267 Höör 8 10 1 0 0 2 0 2 1 0 0 5 7 1 0 0 1 0 2 1 0 0 3 3 0 0 0 1 0 0 0 0 0
111 1270 Tomelilla 6 7 2 0 0 1 1 0 0 0 0 5 6 2 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0
112 1272 Bromölla 5 7 2 0 0 1 0 1 1 0 0 5 7 2 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
113 1273 Osby 4 6 1 0 0 2 1 3 2 0 0 4 6 1 0 0 2 1 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0
114 1275 Perstorp 1 3 0 0 0 2 0 1 1 0 0 1 3 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0
115 1276 Klippan 6 7 1 0 0 5 1 2 1 0 0 5 6 1 0 0 4 1 2 1 0 0 1 1 0 0 0 1 0 0 0 0 0
116 1277 Åstorp 6 7 1 0 0 1 0 2 1 0 0 6 7 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
117 1278 Båstad 5 5 0 0 0 2 0 3 1 0 0 4 4 0 0 0 1 0 3 1 0 0 1 1 0 0 0 1 0 0 0 0 0
118 1280 Malmö 76 103 19 0 0 35 4 28 10 1 0 59 80 17 0 0 13 3 28 10 1 0 17 23 2 0 0 22 1 0 0 0 0
119 1281 Lund 43 52 7 1 0 19 1 4 1 0 1 33 40 6 1 0 5 1 4 1 0 1 10 12 1 0 0 14 0 0 0 0 0
120 1282 Landskrona 15 18 1 0 0 2 1 3 2 0 0 11 12 1 0 0 2 1 3 2 0 0 4 6 0 0 0 0 0 0 0 0 0
121 1283 Helsingborg 52 60 7 0 0 26 4 4 2 0 0 33 34 6 0 0 7 4 4 2 0 0 19 26 1 0 0 19 0 0 0 0 0
122 1284 Höganäs 9 10 1 0 0 1 0 3 2 0 0 6 7 1 0 0 1 0 3 2 0 0 3 3 0 0 0 0 0 0 0 0 0
123 1285 Eslöv 11 16 1 0 0 1 1 3 1 0 0 10 15 1 0 0 1 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
124 1286 Ystad 12 14 1 0 0 7 1 2 2 0 0 9 10 1 0 0 5 1 2 2 0 0 3 4 0 0 0 2 0 0 0 0 0
125 1287 Trelleborg 14 17 2 0 0 1 1 3 1 0 0 12 14 2 0 0 1 1 3 1 0 0 2 3 0 0 0 0 0 0 0 0 0
126 1290 Kristianstad 39 57 7 0 0 19 2 5 1 1 0 33 51 7 0 0 11 2 5 1 1 0 6 6 0 0 0 8 0 0 0 0 0
127 1291 Simrishamn 7 10 1 0 0 1 1 1 1 0 0 4 6 1 0 0 1 1 1 1 0 0 3 4 0 0 0 0 0 0 0 0 0
128 1292 Ängelholm 10 22 2 0 0 5 2 3 2 0 0 10 22 2 0 0 5 2 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0
129 1293 Hässleholm 25 28 1 0 0 3 1 4 1 0 0 23 26 1 0 0 3 1 4 1 0 0 2 2 0 0 0 0 0 0 0 0 0
130 1315 Hylte 6 9 1 0 0 2 1 2 1 0 0 6 8 1 0 0 1 1 2 1 0 0 0 1 0 0 0 1 0 0 0 0 0
131 1380 Halmstad 31 51 5 0 0 22 2 2 2 1 0 28 47 5 0 0 16 2 2 2 1 0 3 4 0 0 0 6 0 0 0 0 0
132 1381 Laholm 14 18 1 0 0 1 1 3 1 0 0 11 15 1 0 0 1 1 3 1 0 0 3 3 0 0 0 0 0 0 0 0 0
133 1382 Falkenberg 21 24 2 0 0 8 1 1 1 0 0 18 21 2 0 0 7 1 1 1 0 0 3 3 0 0 0 1 0 0 0 0 0
134 1383 Varberg 22 37 2 0 0 6 1 2 1 0 0 20 34 2 0 0 3 1 2 1 0 0 2 3 0 0 0 3 0 0 0 0 0
135 1384 Kungsbacka 28 60 3 0 0 14 2 3 1 0 0 21 52 2 0 0 10 2 3 1 0 0 7 8 1 0 0 4 0 0 0 0 0
136 1401 Härryda 14 28 4 0 0 7 0 4 2 0 0 13 27 4 0 0 6 0 4 2 0 0 1 1 0 0 0 1 0 0 0 0 0
137 1402 Partille 10 16 1 0 0 1 1 3 1 0 0 9 15 1 0 0 1 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
138 1407 Öckerö 6 11 1 0 0 1 0 2 0 0 0 5 10 1 0 0 1 0 2 0 0 0 1 1 0 0 0 0 0 0 0 0 0
139 1415 Stenungsund 9 15 4 0 0 5 1 2 2 0 0 8 14 4 0 0 5 1 2 2 0 0 1 1 0 0 0 0 0 0 0 0 0
140 1419 Tjörn 6 9 2 0 0 0 0 1 0 0 0 5 8 2 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0
141 1421 Orust 7 10 1 0 0 1 0 1 1 0 0 4 7 1 0 0 1 0 1 1 0 0 3 3 0 0 0 0 0 0 0 0 0
142 1427 Sotenäs 5 6 1 0 0 1 0 2 2 0 0 5 6 1 0 0 1 0 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0
143 1430 Munkedal 4 6 2 0 0 4 1 2 1 0 0 4 6 2 0 0 2 1 2 1 0 0 0 0 0 0 0 2 0 0 0 0 0
144 1435 Tanum 7 8 1 0 0 1 1 2 1 0 0 7 8 1 0 0 1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
145 1438 Dals-Ed 1 2 2 0 0 1 1 3 1 0 0 1 2 2 0 0 1 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
146 1439 Färgelanda 5 7 1 0 0 0 0 1 1 0 0 3 5 1 0 0 0 0 1 1 0 0 2 2 0 0 0 0 0 0 0 0 0
147 1440 Ale 9 15 2 0 0 2 0 2 1 0 0 8 14 2 0 0 1 0 2 1 0 0 1 1 0 0 0 1 0 0 0 0 0
148 1441 Lerum 16 34 3 0 0 5 1 3 1 0 0 14 32 3 0 0 5 1 3 1 0 0 2 2 0 0 0 0 0 0 0 0 0
149 1442 Vårgårda 6 7 1 0 0 1 0 2 1 0 0 6 7 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
150 1443 Bollebygd 4 6 1 0 0 1 0 0 0 0 0 3 5 1 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
151 1444 Grästorp 1 2 2 0 0 0 0 0 0 0 0 1 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
152 1445 Essunga 3 4 1 0 0 0 1 3 0 0 0 3 4 1 0 0 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0
153 1446 Karlsborg 3 4 1 0 0 1 0 1 1 0 0 2 3 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
154 1447 Gullspång 2 3 1 0 0 0 0 1 1 0 0 2 3 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
155 1452 Tranemo 5 7 5 0 0 1 1 2 1 0 0 5 7 5 0 0 1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
156 1460 Bengtsfors 3 4 2 0 0 1 0 2 1 0 0 3 4 2 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
157 1461 Mellerud 4 6 1 0 0 1 0 3 2 0 0 4 6 1 0 0 1 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0
158 1462 Lilla Edet 5 6 2 0 0 0 1 1 1 0 0 4 5 1 0 0 0 0 1 1 0 0 1 1 1 0 0 0 1 0 0 0 0
159 1463 Mark 15 23 3 0 0 7 1 1 1 0 0 13 21 2 0 0 6 1 1 1 0 0 2 2 1 0 0 1 0 0 0 0 0
160 1465 Svenljunga 7 9 1 0 0 2 0 3 1 0 0 6 8 1 0 0 2 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
161 1466 Herrljunga 7 10 2 0 0 1 0 0 0 0 0 7 10 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
162 1470 Vara 8 12 1 0 0 3 0 4 1 0 0 6 9 1 0 0 2 0 4 1 0 0 2 3 0 0 0 1 0 0 0 0 0
163 1471 Götene 5 7 0 0 0 2 0 1 0 0 0 5 7 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0
164 1472 Tibro 3 4 2 0 0 2 0 0 0 0 0 3 4 2 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
165 1473 Töreboda 4 6 2 0 0 2 2 2 1 0 0 3 5 2 0 0 2 2 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
166 1480 Göteborg 136 179 45 0 0 81 10 28 19 0 2 105 132 41 0 0 44 9 28 19 0 2 31 47 4 0 0 37 1 0 0 0 0
167 1481 Mölndal 18 24 2 0 0 4 1 4 2 0 0 16 22 2 0 0 4 1 4 2 0 0 2 2 0 0 0 0 0 0 0 0 0
168 1482 Kungälv 16 23 2 0 0 5 1 1 1 0 0 12 19 2 0 0 5 1 1 1 0 0 4 4 0 0 0 0 0 0 0 0 0
169 1484 Lysekil 6 7 1 0 0 2 1 1 1 0 0 6 7 1 0 0 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
170 1485 Uddevalla 16 23 3 0 0 24 2 5 2 0 0 13 20 3 0 0 22 2 5 2 0 0 3 3 0 0 0 2 0 0 0 0 0
171 1486 Strömstad 8 9 1 0 0 2 0 3 1 0 0 8 9 1 0 0 2 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
172 1487 Vänersborg 17 32 2 1 0 4 1 5 2 0 0 15 30 2 1 0 2 0 5 2 0 0 2 2 0 0 0 2 1 0 0 0 0
173 1488 Trollhättan 19 33 8 0 0 9 1 4 1 1 0 15 28 8 0 0 4 1 4 1 1 0 4 5 0 0 0 5 0 0 0 0 0
174 1489 Alingsås 16 21 2 0 0 6 1 3 1 0 0 14 19 2 0 0 5 1 3 1 0 0 2 2 0 0 0 1 0 0 0 0 0
175 1490 Borås 36 48 4 0 0 23 3 6 1 1 0 33 44 4 0 0 18 3 6 1 1 0 3 4 0 0 0 5 0 0 0 0 0
176 1491 Ulricehamn 12 15 1 0 0 2 1 3 1 0 0 10 13 1 0 0 2 1 3 1 0 0 2 2 0 0 0 0 0 0 0 0 0
177 1492 Åmål 3 5 4 0 0 3 1 3 1 0 0 2 4 4 0 0 3 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
178 1493 Mariestad 11 14 1 0 0 4 1 1 1 0 0 9 11 1 0 0 3 1 1 1 0 0 2 3 0 0 0 1 0 0 0 0 0
179 1494 Lidköping 17 22 3 0 0 6 1 5 2 0 0 16 20 3 0 0 6 1 5 2 0 0 1 2 0 0 0 0 0 0 0 0 0
180 1495 Skara 7 8 2 0 0 6 1 5 1 0 1 6 7 1 0 0 5 0 5 1 0 1 1 1 1 0 0 1 1 0 0 0 0
181 1496 Skövde 19 25 3 0 0 13 2 3 1 1 0 17 23 3 0 0 6 2 3 1 1 0 2 2 0 0 0 7 0 0 0 0 0
182 1497 Hjo 5 6 2 0 0 1 0 3 2 0 0 5 6 2 0 0 1 0 3 2 0 0 0 0 0 0 0 0 0 0 0 0 0
183 1498 Tidaholm 5 9 2 0 0 2 0 3 1 0 0 5 9 2 0 0 2 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
184 1499 Falköping 14 21 4 0 0 4 1 2 1 0 0 13 20 4 0 0 4 1 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
185 1715 Kil 5 7 1 0 0 1 0 2 1 0 0 5 7 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
186 1730 Eda 4 4 1 0 0 0 0 1 1 0 0 4 4 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
187 1737 Torsby 5 6 3 0 0 1 1 1 1 0 0 5 6 3 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
188 1760 Storfors 2 4 1 0 0 1 0 1 1 0 0 2 3 1 0 0 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 0 0
189 1761 Hammarö 5 11 1 0 0 0 0 0 0 0 0 5 11 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
190 1762 Munkfors 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
191 1763 Forshaga 5 7 6 0 0 1 0 1 1 0 0 5 7 6 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0
192 1764 Grums 4 5 2 0 0 1 0 1 0 0 0 2 3 2 0 0 1 0 1 0 0 0 2 2 0 0 0 0 0 0 0 0 0
193 1765 Årjäng 5 7 1 0 0 1 1 3 1 0 0 4 6 1 0 0 1 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
194 1766 Sunne 7 8 3 0 0 2 1 3 1 0 0 6 7 3 0 0 2 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
195 1780 Karlstad 23 41 6 0 0 22 3 6 2 0 1 20 36 5 0 0 13 3 6 2 0 1 3 5 1 0 0 9 0 0 0 0 0
196 1781 Kristinehamn 7 13 1 0 0 3 1 3 1 0 0 7 13 1 0 0 3 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
197 1782 Filipstad 7 8 3 0 0 1 0 1 1 0 0 6 7 3 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
198 1783 Hagfors 4 7 1 0 0 2 1 3 1 0 0 4 7 1 0 0 2 1 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
199 1784 Arvika 11 15 3 0 0 3 1 2 1 0 0 11 14 3 0 0 2 1 2 1 0 0 0 1 0 0 0 1 0 0 0 0 0
200 1785 Säffle 8 9 3 0 0 1 2 1 1 0 0 6 7 3 0 0 1 2 1 1 0 0 2 2 0 0 0 0 0 0 0 0 0
201 1814 Lekeberg 3 4 1 0 0 1 0 2 1 0 0 3 4 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
202 1860 Laxå 2 3 1 0 0 0 0 0 0 0 0 2 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
203 1861 Hallsberg 6 7 0 0 0 5 1 2 1 0 0 6 7 0 0 0 5 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
204 1862 Degerfors 4 5 2 0 0 1 0 1 1 0 0 4 5 2 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
205 1863 Hällefors 2 4 1 0 0 1 0 1 1 0 0 2 4 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
206 1864 Ljusnarsberg 1 2 1 0 0 0 0 1 1 0 0 1 2 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
207 1880 Örebro 53 68 6 3 0 36 3 18 2 0 1 45 53 6 3 0 25 2 18 2 0 1 8 15 0 0 0 11 1 0 0 0 0
208 1881 Kumla 8 11 2 0 0 1 1 4 2 0 0 8 11 2 0 0 1 1 4 2 0 0 0 0 0 0 0 0 0 0 0 0 0
209 1882 Askersund 5 6 1 0 0 0 0 0 0 0 0 5 6 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
210 1883 Karlskoga 7 12 1 0 0 2 1 3 1 0 0 6 11 1 0 0 1 1 3 1 0 0 1 1 0 0 0 1 0 0 0 0 0
211 1884 Nora 6 7 2 0 0 1 0 3 1 0 0 5 6 2 0 0 1 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
212 1885 Lindesberg 8 11 1 0 0 4 1 3 1 0 0 6 9 1 0 0 4 1 3 1 0 0 2 2 0 0 0 0 0 0 0 0 0
213 1904 Skinnskatteberg 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
214 1907 Surahammar 4 6 1 0 0 2 0 1 0 0 0 4 6 1 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0
215 1960 Kungsör 3 4 1 0 0 1 0 1 1 0 0 3 4 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
216 1961 Hallstahammar 5 7 2 0 0 2 0 1 1 0 0 5 7 2 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0 0
217 1962 Norberg 1 2 1 0 0 0 0 0 0 0 0 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
218 1980 Västerås 49 60 12 0 0 21 5 10 4 1 0 38 42 11 0 0 7 4 10 4 1 0 11 18 1 0 0 14 1 0 0 0 0
219 1981 Sala 11 14 2 0 0 2 1 1 1 0 0 11 14 2 0 0 2 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
220 1982 Fagersta 4 5 1 0 0 1 2 3 1 0 0 3 4 1 0 0 1 2 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
221 1983 Köping 7 12 3 0 0 4 2 2 1 0 0 7 12 3 0 0 4 2 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
222 1984 Arboga 6 8 1 0 0 1 0 3 1 0 0 5 7 1 0 0 1 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
223 2021 Vansbro 4 6 5 0 0 1 0 1 1 0 0 3 5 5 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
224 2023 Malung-Sälen 5 7 4 0 0 1 0 1 1 0 0 5 7 4 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
225 2026 Gagnef 6 7 1 0 0 1 0 2 1 0 0 6 7 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
226 2029 Leksand 9 10 1 0 0 1 1 1 1 0 0 7 8 1 0 0 1 1 1 1 0 0 2 2 0 0 0 0 0 0 0 0 0
227 2031 Rättvik 7 8 2 0 0 1 1 0 0 0 0 7 8 2 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
228 2034 Orsa 5 5 1 0 0 0 0 0 0 0 0 4 4 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
229 2039 Älvdalen 4 4 0 0 0 1 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
230 2061 Smedjebacken 4 6 0 0 0 1 0 0 0 0 0 4 6 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
231 2062 Mora 12 14 1 0 0 2 1 3 1 0 0 11 13 1 0 0 2 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
232 2080 Falun 23 26 3 0 0 7 1 1 1 1 0 21 23 3 0 0 3 1 1 1 1 0 2 3 0 0 0 4 0 0 0 0 0
233 2081 Borlänge 15 20 1 0 0 7 1 3 1 1 0 14 17 1 0 0 4 1 3 1 1 0 1 3 0 0 0 3 0 0 0 0 0
234 2082 Säter 3 4 2 0 0 1 0 1 1 0 0 3 4 2 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
235 2083 Hedemora 8 10 3 0 0 1 3 3 1 0 0 6 7 2 0 0 1 2 3 1 0 0 2 3 1 0 0 0 1 0 0 0 0
236 2084 Avesta 9 12 2 0 0 1 1 3 1 0 0 8 11 2 0 0 1 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
237 2085 Ludvika 11 13 2 0 0 4 1 3 1 0 0 10 12 2 0 0 3 1 3 1 0 0 1 1 0 0 0 1 0 0 0 0 0
238 2101 Ockelbo 2 4 0 0 0 0 0 1 1 0 0 2 4 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
239 2104 Hofors 3 4 1 0 0 1 0 2 1 0 0 3 4 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
240 2121 Ovanåker 7 9 0 0 0 2 0 3 1 0 0 7 9 0 0 0 2 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
241 2132 Nordanstig 7 7 1 0 0 1 0 1 1 0 0 5 5 1 0 0 1 0 1 1 0 0 2 2 0 0 0 0 0 0 0 0 0
242 2161 Ljusdal 8 10 1 0 0 3 0 3 1 0 0 6 7 1 0 0 1 0 3 1 0 0 2 3 0 0 0 2 0 0 0 0 0
243 2180 Gävle 29 36 7 0 0 10 1 3 1 1 0 25 29 7 0 0 4 1 3 1 1 0 4 7 0 0 0 6 0 0 0 0 0
244 2181 Sandviken 12 15 2 0 0 3 1 3 1 0 0 11 14 2 0 0 2 1 3 1 0 0 1 1 0 0 0 1 0 0 0 0 0
245 2182 Söderhamn 12 17 1 0 0 2 0 2 1 0 0 11 15 1 0 0 2 0 2 1 0 0 1 2 0 0 0 0 0 0 0 0 0
246 2183 Bollnäs 12 15 2 0 0 6 1 2 1 0 0 7 9 2 0 0 2 1 2 1 0 0 5 6 0 0 0 4 0 0 0 0 0
247 2184 Hudiksvall 19 24 2 0 0 7 1 3 1 0 0 16 20 1 0 0 6 1 3 1 0 0 3 4 1 0 0 1 0 0 0 0 0
248 2260 Ånge 5 6 2 0 0 1 0 3 1 0 0 4 5 2 0 0 1 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
249 2262 Timrå 7 9 2 0 0 2 0 4 1 0 0 7 9 2 0 0 2 0 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0
250 2280 Härnösand 9 14 1 1 0 3 1 1 1 0 0 8 13 1 1 0 3 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
251 2281 Sundsvall 31 40 6 0 0 13 1 12 6 1 0 24 29 6 0 0 7 1 12 6 1 0 7 11 0 0 0 6 0 0 0 0 0
252 2282 Kramfors 8 10 1 0 0 1 1 2 1 0 0 7 9 1 0 0 1 1 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
253 2283 Sollefteå 12 13 1 0 0 1 1 1 1 0 0 12 13 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
254 2284 Örnsköldsvik 30 35 1 0 0 13 1 6 1 0 0 27 31 1 0 0 10 1 6 1 0 0 3 4 0 0 0 3 0 0 0 0 0
255 2303 Ragunda 2 3 3 0 0 1 0 1 1 0 0 2 3 3 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
256 2305 Bräcke 3 3 0 0 0 1 0 1 1 0 0 3 3 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
257 2309 Krokom 14 16 1 0 0 3 1 3 1 0 0 14 16 1 0 0 2 1 3 1 0 0 0 0 0 0 0 1 0 0 0 0 0
258 2313 Strömsund 8 9 0 0 0 1 0 1 1 0 0 8 9 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
259 2321 Åre 7 7 3 0 0 2 0 3 1 0 0 7 7 3 0 0 2 0 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0
260 2326 Berg 8 10 1 0 0 1 0 1 1 0 0 7 9 1 0 0 1 0 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
261 2361 Härjedalen 8 9 0 0 0 1 0 1 1 0 0 8 9 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
262 2380 Östersund 25 29 1 0 0 14 1 3 1 1 0 20 24 1 0 0 12 1 3 1 1 0 5 5 0 0 0 2 0 0 0 0 0
263 2401 Nordmaling 3 5 1 0 0 1 0 1 1 0 0 3 5 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
264 2403 Bjurholm 1 1 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
265 2404 Vindeln 4 5 2 0 0 0 0 2 1 0 0 4 5 2 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
266 2409 Robertsfors 5 7 1 0 0 0 0 1 1 0 0 5 7 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
267 2417 Norsjö 3 2 1 0 0 1 1 2 1 0 0 3 2 1 0 0 1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
268 2418 Malå 1 1 0 0 0 1 0 2 1 0 0 1 1 0 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
269 2421 Storuman 5 6 0 0 0 2 0 1 1 0 0 5 6 0 0 0 2 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
270 2422 Sorsele 3 3 1 0 0 0 0 2 1 0 0 3 3 1 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
271 2425 Dorotea 2 2 1 0 0 0 0 1 1 0 0 2 2 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
272 2460 Vännäs 3 7 1 0 0 4 0 4 1 0 0 2 6 1 0 0 4 0 4 1 0 0 1 1 0 0 0 0 0 0 0 0 0
273 2462 Vilhelmina 4 7 2 0 0 2 0 3 1 0 0 3 6 1 0 0 2 0 3 1 0 0 1 1 1 0 0 0 0 0 0 0 0
274 2463 Åsele 2 2 0 0 0 0 0 2 1 0 0 2 2 0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
275 2480 Umeå 50 64 4 1 0 14 3 4 1 0 2 43 56 4 1 0 10 3 4 1 0 2 7 8 0 0 0 4 0 0 0 0 0
276 2481 Lycksele 9 12 1 0 0 4 1 1 1 0 0 9 12 1 0 0 4 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
277 2482 Skellefteå 34 38 7 0 0 10 2 4 1 0 0 29 32 7 0 0 7 2 4 1 0 0 5 6 0 0 0 3 0 0 0 0 0
278 2505 Arvidsjaur 2 4 2 0 0 1 1 2 1 0 0 2 4 2 0 0 1 1 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
279 2506 Arjeplog 1 1 1 0 0 1 0 2 1 0 0 1 1 1 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0
280 2510 Jokkmokk 3 4 2 0 1 1 1 3 1 0 0 3 3 2 0 1 1 1 3 1 0 0 0 1 0 0 0 0 0 0 0 0 0
281 2513 Överkalix 2 2 1 0 0 1 0 2 1 0 0 1 1 1 0 0 1 0 2 1 0 0 1 1 0 0 0 0 0 0 0 0 0
282 2514 Kalix 9 10 2 0 0 2 1 2 2 0 0 8 9 2 0 0 2 1 2 2 0 0 1 1 0 0 0 0 0 0 0 0 0
283 2518 Övertorneå 3 4 0 0 0 1 1 1 1 0 0 2 3 0 0 0 1 1 1 1 0 0 1 1 0 0 0 0 0 0 0 0 0
284 2521 Pajala 5 6 2 0 0 1 1 3 1 0 0 4 5 2 0 0 1 1 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
285 2523 Gällivare 9 11 2 0 1 3 1 3 2 0 0 9 10 2 0 1 3 1 3 2 0 0 0 1 0 0 0 0 0 0 0 0 0
286 2560 Älvsbyn 3 5 1 0 0 1 1 1 1 0 0 3 5 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
287 2580 Luleå 32 48 2 0 0 13 1 3 1 0 0 27 43 2 0 0 10 1 3 1 0 0 5 5 0 0 0 3 0 0 0 0 0
288 2581 Piteå 20 29 1 0 0 6 1 3 1 0 0 17 26 1 0 0 6 1 3 1 0 0 3 3 0 0 0 0 0 0 0 0 0
289 2582 Boden 13 15 3 0 0 5 1 1 1 0 0 9 11 3 0 0 5 1 1 1 0 0 4 4 0 0 0 0 0 0 0 0 0
290 2583 Haparanda 5 6 2 0 0 1 0 3 1 0 0 4 5 2 0 0 1 0 3 1 0 0 1 1 0 0 0 0 0 0 0 0 0
291 2584 Kiruna 13 14 2 0 2 4 1 3 1 0 0 12 12 2 0 2 3 1 3 1 0 0 1 2 0 0 0 1 0 0 0 0 0

Binary file not shown.

Binary file not shown.

313
skolverket.R Normal file
View file

@ -0,0 +1,313 @@
# =============================================================================
# skolverket.R · Educational offer dataset by municipality
# =============================================================================
#
# Sources and coverage:
# 1. data/skolenhetsadresser.xlsx Skolverket school unit registry
# (current snapshot; all Skolverket-regulated institution types)
# Sheets: Förskoleklass, Grundskola, Anpassad grundskola, Specialskola,
# Sameskola, Gymnasieskola, Anpassad gymnasieskola, Komvux
# 2. Hardcoded list higher education institutions
# Source: UKÄ (Universitetskanslersämbetet) register, ~40 institutions.
# Each institution-municipality pair is one row; multi-campus institutions
# appear under every municipality that hosts a campus.
# 3. TODO: Yrkeshögskola MYH (Myndigheten för yrkeshögskolan)
# open data at myh.se; no REST API identified so far.
# 4. TODO: Folkhögskola Folkbildningsrådet register at
# folkbildning.se; ~155 institutions across ~100+ municipalities.
#
# Note: the Skolverket planned-educations API (api.skolverket.se) was
# explored but covers only the same types as the xlsx; it is used here
# purely as an optional check in section 03.
#
# Output:
# data/processed/edu_offer.rds : municipality × indicator/count (wide)
# data/processed/edu_offer.csv : same, plain text
library(tidyverse)
library(readxl)
# 00 Helpers -----------------------------------------------------------------
XLSX_PATH <- "data/skolenhetsadresser.xlsx"
# Standardise municipality code column to 4-char zero-padded string
add_muni_code <- function(df) {
df |>
rename(
muni_code = `BELÄGEN I KOMMUN (KOD)`,
muni_name = `BELÄGEN I KOMMUN (NAMN)`
) |>
mutate(muni_code = str_pad(as.character(muni_code), 4, "left", "0"))
}
# Public = Kommunal or Region (state-level public body); else private
categorise_ownership <- function(df) {
mutate(
df,
ownership = if_else(
HUVUDMANNATYP %in% c("Kommunal", "Region", "Statlig"),
"public",
"private"
)
)
}
# Count units by municipality and ownership, then pivot to n_public / n_private / n_total
count_units <- function(df, type_label) {
pivoted <- df |>
add_muni_code() |>
categorise_ownership() |>
count(muni_code, muni_name, ownership) |>
pivot_wider(names_from = ownership, values_from = n, values_fill = 0L)
# Ensure both columns exist even if one ownership type is absent
if (!"public" %in% names(pivoted)) {
pivoted$public <- 0L
}
if (!"private" %in% names(pivoted)) {
pivoted$private <- 0L
}
pivoted |>
mutate(
n_total = public + private,
type = type_label,
n_public = public,
n_private = private
) |>
select(muni_code, muni_name, type, n_total, n_public, n_private)
}
# 01 Read all xlsx sheets ----------------------------------------------------
sheet_map <- c(
"forskoleklass" = "Förskoleklass",
"grundskola" = "Grundskola",
"anpassad_grundskola" = "Anpassad grundskola",
"specialskola" = "Specialskola",
"sameskola" = "Sameskola",
"gymnasieskola" = "Gymnasieskola",
"anpassad_gymnasieskola" = "Anpassad gymnasieskola",
"komvux" = "Komvux"
)
raw <- imap(sheet_map, \(sheet_name, type_label) {
cat("Reading sheet:", sheet_name, "\n")
read_excel(XLSX_PATH, sheet = sheet_name)
})
# 02 Count institutions per municipality and ownership -----------------------
unit_counts <- imap_dfr(raw, \(df, type_label) count_units(df, type_label))
# Komvux: additionally extract SFI-offering units as a separate indicator.
# Column "SVENSKA FÖR INVANDRARE" = "J" means the unit offers SFI.
sfi_counts <- raw[["komvux"]] |>
add_muni_code() |>
categorise_ownership() |>
filter(`SVENSKA FÖR INVANDRARE` == "J") |>
count(muni_code, muni_name, ownership) |>
pivot_wider(names_from = ownership, values_from = n, values_fill = 0L) |>
(\(x) {
if (!"public" %in% names(x)) {
x$public <- 0L
}
x
})() |>
(\(x) {
if (!"private" %in% names(x)) {
x$private <- 0L
}
x
})() |>
mutate(
n_total = public + private,
type = "sfi",
n_public = public,
n_private = private
) |>
select(muni_code, muni_name, type, n_total, n_public, n_private)
unit_counts <- bind_rows(unit_counts, sfi_counts)
# 03 Skolverket API cross-check (optional) -----------------------------------
# The planned-educations API returns the same institution types as the xlsx.
# This block fetches the API data and reports any discrepancies between the two.
# Comment out if offline or if the xlsx is known to be current.
api_cross_check <- tryCatch(
{
cat("\nFetching Skolverket API for cross-check...\n")
base_url <- "https://api.skolverket.se/planned-educations/school-units"
fetch_page <- function(page) {
url <- paste0(base_url, "?page=", page, "&size=100")
resp <- readLines(url, warn = FALSE) |>
paste(collapse = "") |>
jsonlite::fromJSON()
resp$body
}
first <- fetch_page(0)
n_pages <- first$page$totalPages
cat(
" API reports",
first$page$totalElements,
"units across",
n_pages,
"pages\n"
)
all_pages <- map(0:(n_pages - 1), \(p) {
if (p %% 10 == 0) {
cat(" page", p, "/", n_pages, "\n")
}
fetch_page(p)$`_embedded`$listedSchoolUnits
})
api_df <- bind_rows(all_pages) |>
transmute(
muni_code = str_pad(as.character(geographicalAreaCode), 4, "left", "0"),
ownership = if_else(
principalOrganizerType %in% c("Kommunal", "Region", "Statlig"),
"public",
"private"
),
type = map_chr(typeOfSchooling, \(t) {
if (is.null(t) || nrow(t) == 0) {
return(NA_character_)
}
t$code[1]
})
) |>
filter(!is.na(type))
api_summary <- api_df |>
count(muni_code, type, ownership, name = "n_api") |>
mutate(
type = recode(
type,
fsk = "forskoleklass",
gr = "grundskola",
gran = "anpassad_grundskola",
sp = "specialskola",
sam = "sameskola",
gy = "gymnasieskola",
gyan = "anpassad_gymnasieskola",
vuxgy = "komvux",
vuxgr = "komvux",
sfi = "sfi"
)
)
cat(" API cross-check complete\n")
api_summary
},
error = function(e) {
message("API cross-check skipped: ", conditionMessage(e))
NULL
}
)
# 04 Higher education institutions (UKÄ list, hardcoded) ---------------------
# Source: UKÄ register of accredited Swedish higher education institutions.
# Each row = one institution × one municipality (multi-campus → multiple rows).
# Verify against: https://www.uka.se/om-oss/kontakt/larosaetenas-webbplatser.html
he_institutions <- tribble(
~institution , ~muni_code , ~type_he ,
# ---- State universities ----
"Uppsala University" , "0380" , "university" ,
"Stockholm University" , "0180" , "university" ,
"Lund University" , "1281" , "university" ,
"University of Gothenburg" , "1480" , "university" ,
"Umeå University" , "2480" , "university" ,
"Linköping University" , "0580" , "university" ,
"Örebro University" , "1880" , "university" ,
"Karlstad University" , "1780" , "university" ,
# ---- State specialised universities ----
"KTH Royal Institute of Technology" , "0180" , "university" ,
"Karolinska Institutet" , "0184" , "university" , # Solna
"Chalmers University of Technology" , "1480" , "university" , # private, state-grant
"SLU Uppsala" , "0380" , "university" ,
"SLU Umeå" , "2480" , "university" ,
"SLU Alnarp (Lomma)" , "1262" , "university" ,
"SLU Skara" , "1495" , "university" ,
# ---- State university colleges ----
"Blekinge Institute of Technology" , "1080" , "university_college" , # Karlskrona
"Dalarna University Falun" , "2080" , "university_college" ,
"Dalarna University Borlänge" , "2081" , "university_college" ,
"University of Gävle" , "2180" , "university_college" ,
"Halmstad University" , "1380" , "university_college" ,
"Kristianstad University" , "1290" , "university_college" ,
"Linnaeus University Växjö" , "0780" , "university_college" ,
"Linnaeus University Kalmar" , "0880" , "university_college" ,
"Malmö University" , "1280" , "university_college" ,
"Mälardalen University Västerås" , "1980" , "university_college" ,
"Mälardalen University Eskilstuna" , "0484" , "university_college" ,
"Mid Sweden University Sundsvall" , "2281" , "university_college" ,
"Mid Sweden University Östersund" , "2380" , "university_college" ,
"Södertörn University" , "0126" , "university_college" , # Huddinge
"University of Borås" , "1490" , "university_college" ,
"University of Skövde" , "1496" , "university_college" ,
"University West" , "1488" , "university_college" , # Trollhättan
# ---- Private accredited institutions ----
"Stockholm School of Economics" , "0180" , "university_college" ,
"Jönköping University" , "0680" , "university_college" ,
# ---- Art, music, design, sport ----
"Konstfack" , "0180" , "university_college" ,
"Royal University College of Music (KMH)" , "0180" , "university_college" ,
"Stockholm University of the Arts" , "0180" , "university_college" ,
"Royal Institute of Art" , "0180" , "university_college" ,
"Beckmans College of Design" , "0180" , "university_college" ,
"Swedish School of Sport and Health Sciences" , "0180" , "university_college" ,
# ---- Defence / health ----
"Swedish Defence University" , "0180" , "university_college" ,
"Sophiahemmet University" , "0180" , "university_college" ,
"Ersta Sköndal Bräcke University College" , "0180" , "university_college" ,
"Röda Korsets Högskola" , "0180" , "university_college" ,
"Newmaninstitutet" , "0380" , "university_college"
)
he_counts <- he_institutions |>
count(muni_code, type_he, name = "n_total") |>
rename(type = type_he) |>
# All Swedish HE institutions are state-funded or receive >90% public funding;
# public/private distinction used for school units does not apply here.
mutate(n_public = n_total, n_private = 0L, muni_name = NA_character_)
# 05 Combine all sources and reshape to wide ---------------------------------
long <- bind_rows(
unit_counts,
he_counts
)
# Load the municipality reference to fill in any missing names and ensure
# all 290 m_sample municipalities appear (with 0s for absent institution types)
munis <- readRDS("data/processed/m_sample.rds") |>
select(muni_code = code, muni_name_ref = municipality)
all_types <- unique(long$type)
wide <- munis |>
cross_join(tibble(type = all_types)) |>
left_join(
long |> select(muni_code, type, n_total, n_public, n_private),
by = c("muni_code", "type")
) |>
mutate(
n_total = replace_na(n_total, 0L),
n_public = replace_na(n_public, 0L),
n_private = replace_na(n_private, 0L)
) |>
pivot_wider(
names_from = type,
values_from = c(n_total, n_public, n_private),
names_glue = "{type}_{.value}"
) |>
rename(municipality = muni_name_ref, code = muni_code)
# 06 Save --------------------------------------------------------------------
write_rds(wide, "data/processed/edu_offer.rds")
write_csv(wide, "data/processed/edu_offer.csv")

View file

@ -1,8 +1,8 @@
# 00-Libraries -----------------------------------------------------------------
# 00 - Libraries ---------------------------------------------------------------
library(tidyverse)
library(readxl)
# 01-Import --------------------------------------------------------------------
# 01 - Import ------------------------------------------------------------------
# Municipalities_db.xlsx has two title rows before the merged-cell header:
# Row 1: "Municipalities Database" (title)

View file

@ -35,11 +35,11 @@
library(tidyverse)
# 00-Load ----------------------------------------------------------------------
# 00 - Load --------------------------------------------------------------------
municipalities_raw <- read_rds("data/processed/m_raw.rds")
# Panel: 17 110 rows (290 municipalities × ~59 years), 257 columns.
# 01-Characterise each variable's availability ---------------------------------
# 01 - Characterise each variable's availability -------------------------------
# 1a. Full dataset: first and last year with any non-NA value.
availability_full <- municipalities_raw |>
pivot_longer(
@ -69,7 +69,7 @@ availability_window <- municipalities_raw |>
window_last_year = max(year)
)
# 02-Extract the 2022 slice and assess NAs -------------------------------------
# 02 - Extract the 2022 slice and assess NAs -----------------------------------
m_2022 <- municipalities_raw |> filter(year == 2022)
n_munic <- nrow(m_2022) # 290
@ -78,7 +78,7 @@ na_2022 <- m_2022 |>
pivot_longer(everything(), names_to = "variable", values_to = "n_na") |>
mutate(pct_na = n_na / n_munic)
# 03-Classify every variable ---------------------------------------------------
# 03 - Classify every variable -------------------------------------------------
variable_plan <- na_2022 |>
left_join(availability_full, by = "variable") |>
left_join(availability_window, by = "variable") |>
@ -117,7 +117,8 @@ variable_plan <- na_2022 |>
)
)
# 04-Backfill A: window [2020, 2021] Per-municipality, most recent non-NA value.
# 04 - Backfill A: window [2020, 2021] Per-municipality, most recent non-NA
# value.
vars_window <- variable_plan |>
filter(action == "backfill_window") |>
pull(variable)
@ -143,7 +144,7 @@ window_wide <- window_long |>
select(-year) |>
pivot_wider(names_from = variable, values_from = value)
# 05-Backfill B: census / periodic Per-municipality, year closest to 2022 in
# 05 - Backfill B: census / periodic Per-municipality, year closest to 2022 in
# either direction.
# (Applies to EU parliament election variables: 2024 is 2 years away,
# 2019 is 3 years away, so 2024 will be selected for all municipalities.)
@ -174,7 +175,7 @@ census_wide <- census_long |>
select(-year, -distance) |>
pivot_wider(names_from = variable, values_from = value)
# 06-Backfill C: discontinued --------------------------------------------------
# 06 - Backfill C: discontinued ------------------------------------------------
vars_disc <- variable_plan |>
filter(action == "backfill_disc") |>
pull(variable)
@ -196,14 +197,14 @@ disc_wide <- disc_long |>
select(-year) |>
pivot_wider(names_from = variable, values_from = value)
# 07-Apply all fills (window first, then census and disc which only touch the
# 07 - Apply all fills (window first, then census and disc which only touch the
# still-NA cells, i.e. the 100%-missing variables ------------------------------
m_2022_filled <- m_2022 |>
rows_patch(window_wide, by = "code", unmatched = "ignore") |>
rows_patch(census_wide, by = "code", unmatched = "ignore") |>
rows_patch(disc_wide, by = "code", unmatched = "ignore")
# 08-Remove truly empty variables and the redundant year column ----------------
# 08 - Remove truly empty variables and the redundant year column --------------
vars_drop <- variable_plan |> filter(action == "drop") |> pull(variable)
m_sample <- m_2022_filled |>
@ -215,7 +216,7 @@ na_remaining <- m_sample |>
pivot_longer(everything(), names_to = "variable", values_to = "n_na_final") |>
filter(n_na_final > 0)
# 09-Audit ---------------------------------------------------------------------
# 09 - Audit -------------------------------------------------------------------
# Combine source-year info from all three fill paths
source_years <- bind_rows(
window_source_year,
@ -304,6 +305,6 @@ sampling_audit <- variable_plan |>
arrange(action, fill_type, desc(years_from_2022))
# 10-Save ----------------------------------------------------------------------
# 10 - Save --------------------------------------------------------------------
write_rds(m_sample, "data/processed/m_sample.rds")
write_csv(sampling_audit, "data/processed/sampling_audit.csv")

196
src/municipalities/02-CA.R Normal file
View file

@ -0,0 +1,196 @@
# =============================================================================
# 02-CA.R · Correspondence Analysis of the 2022 municipal cross-section
# =============================================================================
#
# Bourdieusian framework:
# - Individuals (rows): 290 Swedish municipalities
# - Active columns: population-composition counts — variables that all
# measure "number of residents with attribute X",
# sharing a common unit (persons). The active set is
# deliberately restricted to age structure,
# educational capital (Swedish-born, by gender),
# employment sector, and national origin. These
# variables together define the compositional profile
# of the municipality's resident population.
# - col.sup (a): educational provision counts — the research object
# - col.sup (b): political vote and council counts — outcomes
# - col.sup (c): infrastructure & mobility counts — dwellings,
# vehicles, commuter flows, agricultural enterprises,
# livestock; genuine counts but measuring different
# entities (not persons), so they cannot share a
# contingency table with the active columns
# - Outside CA: rates, proportions, continuous measures, and
# count variables measuring event flows (births,
# deaths, migration) → correlated with CA row
# scores post-hoc
#
# Why restrict active variables to person-counts?
# CA chi-square distance has a clean compositional interpretation only when
# all active columns measure the same type of unit. When counts of persons,
# dwellings, farms, and vehicles share a row, the row total is meaningless
# and chi-square distance becomes a weighted average of incompatible profiles.
# Restricting active columns to person-counts ensures that chi-square distance
# directly compares "what fraction of the population has attribute X?" across
# municipalities, independently of population size.
#
# Outputs:
# data/processed/ca_exploratory.rds - CA result (FactoMineR object)
# data/processed/ca_var_groups.rds - variable group lists
library(tidyverse)
library(FactoMineR)
# 00-Load ----------------------------------------------------------------------
m_sample <- read_rds("data/processed/m_sample.rds")
all_vars <- setdiff(names(m_sample), c("code", "municipality"))
# 01-Exclude genuinely uninformative variables ---------------------------------
# Removed from every part of the analysis: redundant totals, geographic areas,
# and always-zero columns that add no discriminating information.
truly_exclude <- c(
# Redundant totals (sum of components already included elsewhere)
"population",
"livestock_total",
"agricultural_enterprises_total",
"number_of_registered_passenger_cars_by_status_total",
# Geographic areas (ha / km²) — not counts of entities
"land_area_ha",
all_vars[str_detect(all_vars, "^type_of_land_")],
all_vars[str_detect(all_vars, "^use_of_land_")],
"forest", "open_land", "total_green_space",
all_vars[str_detect(all_vars, "^inland_water")],
all_vars[str_detect(all_vars, "^seawater")],
all_vars[str_detect(all_vars, "^the_four_large")],
# Always-zero columns
"number_of_owner_occupied_dwellings_by_type_of_building_other_buildings",
"number_of_owner_occupied_dwellings_by_type_of_building_special_housing"
)
analysis_vars <- setdiff(all_vars, truly_exclude)
# 02-Define variable roles -----------------------------------------------------
# (a) Educational provision: the research object → col.sup
col_sup_edu <- analysis_vars[
str_detect(analysis_vars, "^adult_students_") |
str_detect(analysis_vars, "^admitted_students_") |
str_detect(analysis_vars, "^graduates_from_") |
str_detect(analysis_vars, "^location_of_home_vs_university_")
]
# (b) Political vote and council counts → col.sup
col_sup_politics <- analysis_vars[
str_detect(analysis_vars, "^votes_by_party") |
str_detect(analysis_vars, "^entitled_to_vote_by_education_level") |
str_detect(analysis_vars, "^elected_members")
]
# (c) Infrastructure, mobility, and event counts → col.sup
# Genuine counts but measuring dwellings, vehicles, farms, animals, or flows
# rather than resident persons. Projecting them as supplementary shows how
# they relate to the population-composition space without distorting it.
col_sup_infra <- analysis_vars[
str_detect(analysis_vars,
"^number_of_(rented|tenant_owned|owner_occupied)_dwellings") |
str_detect(analysis_vars, "^number_of_registered_passenger_cars_") |
str_detect(analysis_vars, "^workplaces_") |
str_detect(analysis_vars, "^agricultural_enterprises_") |
str_detect(analysis_vars, "^livestock_") |
analysis_vars %in% c(
"sex_men", "sex_women",
"employment_by_gender_men", "employment_by_gender_women",
"number_of_inmigrations", "number_of_outmigrations",
"births", "deaths", "marriages", "divorces",
"buildings", "buildings_for_seasonal_use",
"concentrations_of_holiday_homes", "holiday_home_areas",
"social_assistance_number_of_receiver_households",
"urban_residences_proximity_to_public_green_areas_500_meters_or_less",
"number_of_localities"
)
]
col_sup_vars <- c(col_sup_edu, col_sup_politics, col_sup_infra)
# Active: population-composition person-counts
# All five groups answer "how many residents have attribute X?" and therefore
# share a common denominator — the resident population. No pre-processing
# or proportionalization is needed: CA row-profile normalisation already
# removes the size effect, and chi-square distance directly compares
# compositional profiles.
active_vars <- analysis_vars[
(str_detect(analysis_vars, "^age_") |
str_detect(analysis_vars, "^education_level_of_swedish_men_") |
str_detect(analysis_vars, "^education_level_of_swedish_women_") |
str_detect(analysis_vars, "^employment_by_activity_sectors_") |
str_detect(analysis_vars, "^birth_country_")) &
!analysis_vars %in% col_sup_vars
]
# Everything else → post-hoc correlations with CA dimensions
outside_ca <- setdiff(analysis_vars, c(active_vars, col_sup_vars))
cat(
"Active (person-count population composition): ", length(active_vars), "\n",
"col.sup educational provision: ", length(col_sup_edu), "\n",
"col.sup political vote counts: ", length(col_sup_politics), "\n",
"col.sup infrastructure / event counts: ", length(col_sup_infra), "\n",
"Outside CA (rates / continuous / other): ", length(outside_ca), "\n"
)
# 03-Build CA matrix -----------------------------------------------------------
X <- m_sample |>
select(all_of(c(active_vars, col_sup_vars))) |>
as.data.frame()
rownames(X) <- m_sample$municipality
na_count <- sum(is.na(X))
if (na_count > 0) {
cat("\nReplacing", na_count, "NAs with 0 in the CA matrix\n")
X[is.na(X)] <- 0L
}
idx_sup <- seq(length(active_vars) + 1L, ncol(X))
# 04-Run CA --------------------------------------------------------------------
ca <- CA(X, ncp = 10, col.sup = idx_sup, graph = FALSE)
cat("\nEigenvalues (first 10 dimensions):\n")
print(round(ca$eig[1:10, ], 3))
contribs <- ca$col$contrib |>
as.data.frame() |>
rownames_to_column("variable")
for (d in paste0("Dim ", 1:5)) {
top5 <- contribs |> slice_max(.data[[d]], n = 5) |> pull(variable)
cat("\nTop contributors Dim", str_extract(d, "[0-9]+"), ":\n")
cat(paste0(" ", top5), sep = "\n")
}
# 05-Post-hoc: correlate row scores with outside-CA variables ------------------
ca_row_coords <- as.data.frame(ca$row$coord)
outside_data <- m_sample |>
select(all_of(outside_ca)) |>
mutate(across(everything(), \(x) {
m <- mean(x, na.rm = TRUE)
replace_na(x, if (is.finite(m)) m else 0)
}))
posthoc_cor <- cor(ca_row_coords, outside_data, use = "pairwise.complete.obs") |>
as.data.frame() |>
rownames_to_column("dimension")
# 06-Save ----------------------------------------------------------------------
write_rds(ca, "data/processed/ca_exploratory.rds")
write_rds(
list(
active = active_vars,
edu = col_sup_edu,
politics = col_sup_politics,
infra = col_sup_infra,
outside = outside_ca
),
"data/processed/ca_var_groups.rds"
)
write_csv(posthoc_cor, "data/processed/ca_posthoc_cor.csv")

View file

@ -0,0 +1,117 @@
# =============================================================================
# 03-attainment-ts.R · Educational attainment time-series from SCB PxWeb
# =============================================================================
#
# Table: UF0506B/Utbildning
# "Befolkning 16-74 år efter region, utbildningsnivå, ålder och kön. År 1985-2025"
#
# We fetch ages 25-64 (standard working-age window for education attainment),
# both genders, all 7 SUN education levels, for selected years.
# The API imposes an undocumented cell limit (~150k per request), so we
# batch across municipalities (50 per request).
#
# Education levels (SUN):
# 1-2 = förgymnasial (pre-secondary)
# 3-4 = gymnasial (upper secondary)
# 5-6 = eftergymnasial (post-secondary, non-doctoral)
# 7 = forskarutbildning (doctoral)
#
# Output: data/processed/attainment_ts.rds
# Columns: code, year, edu_level (1-7), n
# Also a summary: code, year, pct_postsec, n_25_64
library(tidyverse)
library(httr)
library(jsonlite)
SCB_URL <- "https://api.scb.se/OV0104/v1/doris/sv/ssd/START/UF/UF0506/UF0506B/Utbildning"
YEARS <- c("2000", "2005", "2010", "2015", "2022")
LEVELS <- as.list(as.character(1:7))
AGES <- as.list(as.character(25:64))
GENDERS <- list("1", "2")
# Fetch municipality codes from table metadata
meta <- fromJSON(content(GET(SCB_URL), "text", encoding = "UTF-8"))
munis <- Filter(\(x) nchar(x) == 4, meta$variables$values[[1]])
cat("Municipalities to fetch:", length(munis), "\n")
# Batch fetch: 50 municipalities per request
fetch_batch <- function(muni_batch) {
query <- list(
query = list(
list(code = "Region",
selection = list(filter = "item", values = as.list(muni_batch))),
list(code = "Alder",
selection = list(filter = "item", values = AGES)),
list(code = "UtbildningsNiva",
selection = list(filter = "item", values = LEVELS)),
list(code = "Kon",
selection = list(filter = "item", values = GENDERS)),
list(code = "Tid",
selection = list(filter = "item", values = as.list(YEARS)))
),
response = list(format = "json")
)
resp <- POST(
SCB_URL,
body = toJSON(query, auto_unbox = TRUE),
encode = "raw",
content_type("application/json"),
timeout(60)
)
if (status_code(resp) != 200) {
stop("HTTP ", status_code(resp), " for batch starting at ", muni_batch[1])
}
d <- fromJSON(content(resp, "text", encoding = "UTF-8"))$data
# key is a list of character vectors: [region, age, edu_level, gender, year]
keys <- do.call(rbind, d$key)
tibble(
code = keys[, 1],
age = as.integer(keys[, 2]),
edu_level = as.integer(keys[, 3]),
gender = as.integer(keys[, 4]),
year = as.integer(keys[, 5]),
n = as.integer(unlist(d$values))
)
}
batches <- split(munis, ceiling(seq_along(munis) / 50))
raw_list <- vector("list", length(batches))
for (i in seq_along(batches)) {
cat(" Fetching batch", i, "/", length(batches),
"(munis", batches[[i]][1], "", tail(batches[[i]], 1), ")\n")
raw_list[[i]] <- tryCatch(
fetch_batch(batches[[i]]),
error = function(e) {
message(" Batch ", i, " failed: ", conditionMessage(e))
NULL
}
)
Sys.sleep(0.3)
}
raw <- bind_rows(compact(raw_list))
cat("Total rows fetched:", nrow(raw), "\n")
# Aggregate: sum across ages and genders → n per (code, year, edu_level)
attainment <- raw |>
group_by(code, year, edu_level) |>
summarise(n = sum(n, na.rm = TRUE), .groups = "drop")
# Summary: % with post-secondary education among 25-64 year olds
attainment_summary <- attainment |>
group_by(code, year) |>
summarise(
n_total = sum(n),
n_postsec = sum(n[edu_level >= 5]),
pct_postsec = 100 * n_postsec / n_total,
.groups = "drop"
)
write_rds(attainment, "data/processed/attainment_ts.rds")
write_rds(attainment_summary, "data/processed/attainment_summary.rds")
cat("Saved attainment_ts.rds and attainment_summary.rds\n")
cat("Years:", paste(sort(unique(attainment$year)), collapse = ", "), "\n")
cat("Municipalities:", n_distinct(attainment$code), "\n")

View file

@ -75,4 +75,4 @@ Overall, this graph suggests many things. First, the fact that the axis 1 explai
\newpage
```
## Municipalities and ? (CA n°2)
## Municipalities and ? (CA n°2)