swissMunicipalities gives access to official historicized lists of municipalities of Switzerland using the official REST API of the Swiss Federal Statistical Office.
More information about the API can be found here.
Get historicized lists of Swiss municipalities
Snapshot
Use get_snapshots()
to get a “snapshot” of all municipalities (Level
= 1), districts (Level
= 2) and cantons (Level
= 3) as of today.
snapshot <- get_snapshots() # snapshot of today by default
snapshot
## # A tibble: 2,300 × 29
## Identi…¹ Valid…² ValidTo Level Parent Name_en Name_fr Name_de Name_it ABBRE…³
## <dbl> <chr> <lgl> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr>
## 1 1 12.09.… NA 1 NA Zürich Zürich Zürich Zürich ZH
## 2 10053 12.09.… NA 2 1 Bezirk… Bezirk… Bezirk… Bezirk… Affolt…
## 3 10575 12.09.… NA 3 10053 Stalli… Stalli… Stalli… Stalli… <NA>
## 4 11742 12.09.… NA 3 10053 Affolt… Affolt… Affolt… Affolt… <NA>
## 5 11801 12.09.… NA 3 10053 Bonste… Bonste… Bonste… Bonste… <NA>
## 6 11992 01.01.… NA 3 10053 Hausen… Hausen… Hausen… Hausen… <NA>
## 7 12249 12.09.… NA 3 10053 Heding… Heding… Heding… Heding… <NA>
## 8 12433 12.09.… NA 3 10053 Mettme… Mettme… Mettme… Mettme… <NA>
## 9 12497 12.09.… NA 3 10053 Obfeld… Obfeld… Obfeld… Obfeld… <NA>
## 10 12671 01.01.… NA 3 10053 Kappel… Kappel… Kappel… Kappel… <NA>
## # … with 2,290 more rows, 19 more variables: ABBREV_1_Text_fr <chr>,
## # ABBREV_1_Text_de <chr>, ABBREV_1_Text_it <chr>, ABBREV_1_Text <chr>,
## # CODE_OFS_1_Text_en <dbl>, CODE_OFS_1_Text_fr <dbl>,
## # CODE_OFS_1_Text_de <dbl>, CODE_OFS_1_Text_it <dbl>, CODE_OFS_1_Text <dbl>,
## # INSCRIPTION_1_Text_en <dbl>, INSCRIPTION_1_Text_fr <dbl>,
## # INSCRIPTION_1_Text_de <dbl>, INSCRIPTION_1_Text_it <dbl>,
## # INSCRIPTION_1_Text <dbl>, REC_TYPE_1_Text_en <lgl>, …
By default, the FSO number is returned. To get the historicized ID, add hist_id = TRUE
in the get_snapshots()
function.
If you want to get a snapshot of a given period, use the that exist for at least part of the specified period (or of a specified day when start_period
and end_period
have the exact same date).
get_snapshots(start_period = "2023-01-01", end_period = "2023-12-31")
## # A tibble: 2,305 × 34
## Identi…¹ Valid…² ValidTo Level Parent Name_en Name_fr Name_de Name_it ABBRE…³
## <dbl> <chr> <chr> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr>
## 1 1 12.09.… <NA> 1 NA Zürich Zürich Zürich Zürich ZH
## 2 10053 12.09.… <NA> 2 1 Bezirk… Bezirk… Bezirk… Bezirk… Affolt…
## 3 10575 12.09.… <NA> 3 10053 Stalli… Stalli… Stalli… Stalli… <NA>
## 4 11742 12.09.… <NA> 3 10053 Affolt… Affolt… Affolt… Affolt… <NA>
## 5 11801 12.09.… <NA> 3 10053 Bonste… Bonste… Bonste… Bonste… <NA>
## 6 11992 01.01.… <NA> 3 10053 Hausen… Hausen… Hausen… Hausen… <NA>
## 7 12249 12.09.… <NA> 3 10053 Heding… Heding… Heding… Heding… <NA>
## 8 12433 12.09.… <NA> 3 10053 Mettme… Mettme… Mettme… Mettme… <NA>
## 9 12497 12.09.… <NA> 3 10053 Obfeld… Obfeld… Obfeld… Obfeld… <NA>
## 10 12671 01.01.… <NA> 3 10053 Kappel… Kappel… Kappel… Kappel… <NA>
## # … with 2,295 more rows, 24 more variables: ABBREV_1_Text_fr <chr>,
## # ABBREV_1_Text_de <chr>, ABBREV_1_Text_it <chr>, ABBREV_1_Text <chr>,
## # CODE_OFS_1_Text_en <dbl>, CODE_OFS_1_Text_fr <dbl>,
## # CODE_OFS_1_Text_de <dbl>, CODE_OFS_1_Text_it <dbl>, CODE_OFS_1_Text <dbl>,
## # INSCRIPTION_1_Text_en <dbl>, INSCRIPTION_1_Text_fr <dbl>,
## # INSCRIPTION_1_Text_de <dbl>, INSCRIPTION_1_Text_it <dbl>,
## # INSCRIPTION_1_Text <dbl>, RADIATION_1_Text_en <dbl>, …
ℹ️ When using
start_period
andend_period
arguments, the date should be in format “yyyy-mm-dd” (for example “2024-08-01”).
Using the Level
column, you can extract the existing list of cantons (Level
= 1), districts (Level
= 2) and municipalities (Level
= 3) and join them to consolidate the municipality dataset.
library(dplyr) # just for data wrangling examples
municipalities <- snapshot |>
filter(Level == 3) |>
rename_with(~ paste0(.x, "_municipality", recycle0 = TRUE)) |>
select(-Level_municipality)
districts <- snapshot |>
filter(Level == 2) |>
rename_with(~ paste0(.x, "_district", recycle0 = TRUE)) |>
select(-Level_district)
cantons <- snapshot |>
filter(Level == 1) |>
rename_with(~ paste0(.x, "_canton", recycle0 = TRUE)) |>
select(-Level_canton)
# consolidate municipality data with districts and cantons levels
municipalities_consolidated <- municipalities |>
left_join(districts, by = join_by(Parent_municipality == Identifier_district)) |>
left_join(cantons, by = join_by(Parent_district == Identifier_canton)) |>
rename(Identifier_district = Parent_municipality, Identifier_canton = Parent_district) |>
select(starts_with(c("Identifier", "Name", "ABBREV", "Valid")), everything()) |>
arrange(Identifier_municipality, Identifier_district)
# get all municipalities of St. Gallen for the given period
municipalities_consolidated |>
filter(Name_de_canton == "St. Gallen")
## # A tibble: 75 × 82
## Identifier_…¹ Ident…² Ident…³ Name_…⁴ Name_…⁵ Name_…⁶ Name_…⁷ Name_…⁸ Name_…⁹
## <dbl> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 14378 10266 17 Häggen… Häggen… Häggen… Häggen… Wahlkr… Wahlkr…
## 2 14379 10266 17 Muolen Muolen Muolen Muolen Wahlkr… Wahlkr…
## 3 14380 10266 17 St. Ga… St. Ga… St. Ga… St. Ga… Wahlkr… Wahlkr…
## 4 14381 10266 17 Witten… Witten… Witten… Witten… Wahlkr… Wahlkr…
## 5 14382 10265 17 Berg (… Berg (… Berg (… Berg (… Wahlkr… Wahlkr…
## 6 14383 10266 17 Eggers… Eggers… Eggers… Eggers… Wahlkr… Wahlkr…
## 7 14384 10265 17 Goldach Goldach Goldach Goldach Wahlkr… Wahlkr…
## 8 14385 10265 17 Mörsch… Mörsch… Mörsch… Mörsch… Wahlkr… Wahlkr…
## 9 14386 10265 17 Rorsch… Rorsch… Rorsch… Rorsch… Wahlkr… Wahlkr…
## 10 14387 10265 17 Rorsch… Rorsch… Rorsch… Rorsch… Wahlkr… Wahlkr…
## # … with 65 more rows, 73 more variables: Name_de_district <chr>,
## # Name_it_district <chr>, Name_en_canton <chr>, Name_fr_canton <chr>,
## # Name_de_canton <chr>, Name_it_canton <chr>,
## # ABBREV_1_Text_en_municipality <chr>, ABBREV_1_Text_fr_municipality <chr>,
## # ABBREV_1_Text_de_municipality <chr>, ABBREV_1_Text_it_municipality <chr>,
## # ABBREV_1_Text_municipality <chr>, ABBREV_1_Text_en_district <chr>,
## # ABBREV_1_Text_fr_district <chr>, ABBREV_1_Text_de_district <chr>, …
Note that the CODE_OFS*
variables refers to the official Swiss community identification number (also called “GEOSTAT”/“BFS” number) and the CODE_HIST*
corresponds to the “historical number”.
Mutations
Access all the mutation list which describes all changes related to municipalities that occurred during the specified period.
To exclude records that only concern territory changes, use include_territory_exchange = FALSE
.
get_mutations(
start_period = "2023-01-01",
end_period = "2023-12-31",
include_territory_exchange = FALSE
)
## # A tibble: 13 × 14
## MutationNum…¹ Mutat…² Initi…³ Initi…⁴ Initi…⁵ Initi…⁶ Initi…⁷ Initi…⁸ Termi…⁹
## <dbl> <chr> <dbl> <dbl> <chr> <dbl> <chr> <dbl> <dbl>
## 1 3964 01.01.… 11735 21 Adlikon 10082 Bezirk… 29 16621
## 2 3964 01.01.… 12173 32 Humlik… 10082 Bezirk… 29 16621
## 3 3964 01.01.… 13214 30 Andelf… 10082 Bezirk… 26 16621
## 4 3965 01.01.… 15116 536 Diemer… 10288 Verwal… 29 16622
## 5 3966 01.01.… 14441 3372 Hemberg 10264 Wahlkr… 29 16623
## 6 3966 01.01.… 14444 3375 Oberhe… 10264 Wahlkr… 29 16623
## 7 3966 01.01.… 14950 3378 Necker… 10264 Wahlkr… 26 16623
## 8 3967 01.01.… 13302 6744 La Cha… 10225 Distri… 29 16624
## 9 3968 01.01.… 11503 4133 Burg (… 10022 Bezirk… 29 16625
## 10 3969 01.01.… 10849 4179 Ueken 10021 Bezirk… 29 16626
## 11 3969 01.01.… 12317 4166 Herzna… 10021 Bezirk… 29 16626
## 12 3970 01.01.… 13334 6787 Damphr… 10226 Distri… 29 16627
## 13 3970 01.01.… 13340 6793 Lugnez 10226 Distri… 29 16627
## # … with 5 more variables: TerminalCode <dbl>, TerminalName <chr>,
## # TerminalParentHistoricalCode <dbl>, TerminalParentName <chr>,
## # TerminalStep <dbl>, and abbreviated variable names ¹MutationNumber,
## # ²MutationDate, ³InitialHistoricalCode, ⁴InitialCode, ⁵InitialName,
## # ⁶InitialParentHistoricalCode, ⁷InitialParentName, ⁸InitialStep,
## # ⁹TerminalHistoricalCode
Correspondances
Get the municipality correspondances, which indicates for each municipality existing at the start_period
time, which is/are the corresponding municipality(ies) at the end_period
time.
To exclude districts and municipalities that have not undergone any changes, add include_unmodified = FALSE
.
get_correspondances(
start_period = "2022-01-01",
end_period = "2022-12-31",
include_unmodified = FALSE,
include_territory_exchange = FALSE
)
## # A tibble: 5 × 12
## InitialHisto…¹ Initi…² Initi…³ Initi…⁴ Initi…⁵ Initi…⁶ Termi…⁷ Termi…⁸ Termi…⁹
## <dbl> <dbl> <chr> <dbl> <chr> <dbl> <dbl> <dbl> <chr>
## 1 12412 5197 Melano 10003 Distre… 29 16619 5240 Val Ma…
## 2 12762 5195 Marogg… 10003 Distre… 29 16619 5240 Val Ma…
## 3 12848 5219 Rovio 10003 Distre… 29 16619 5240 Val Ma…
## 4 14099 3103 Rüte 10252 Kanton… 29 16620 3112 Schwen…
## 5 14101 3105 Schwen… 10252 Kanton… 29 16620 3112 Schwen…
## # … with 3 more variables: TerminalParentHistoricalCode <dbl>,
## # TerminalParentName <chr>, TerminalStep <dbl>, and abbreviated variable
## # names ¹InitialHistoricalCode, ²InitialCode, ³InitialName,
## # ⁴InitialParentHistoricalCode, ⁵InitialParentName, ⁶InitialStep,
## # ⁷TerminalHistoricalCode, ⁸TerminalCode, ⁹TerminalName
Levels
The geographical levels offer several classifications of municipalities according to, for example, linguistic regions, agglomerations or even the degree of urbanization.
By default, the FSO number is returned. To get the historicized ID, add hist_id = TRUE
in the get_levels()
function. You can change the label_languages
between French (“fr”), German (“de”), Italian (“it”) and English (“en”).
get_levels(label_languages = "de") # as of today by default
## # A tibble: 2,131 × 57
## Identifier Name_de CODE_…¹ HR_HG…² HR_HG…³ HR_HG…⁴ HR_HG…⁵ HR_AG…⁶ HR_AG…⁷
## <dbl> <chr> <dbl> <dbl> <chr> <dbl> <chr> <dbl> <chr>
## 1 10009 Villnache… 4122 19 Aargau 10023 Bezirk… 0 keine …
## 2 10078 Vionnaz 6158 23 Valais… 10013 Distri… 0 keine …
## 3 10157 Speicher 3023 15 Appenz… 10098 Bezirk… 3203 St. Ga…
## 4 10159 Zwischber… 6011 23 Valais… 10035 Bezirk… 6002 Brig –…
## 5 10162 Villars-s… 2228 10 Fribou… 10104 Distri… 2196 Fribou…
## 6 10165 Villarsel… 2230 10 Fribou… 10104 Distri… 2196 Fribou…
## 7 10242 Wila 181 1 Zürich 10076 Bezirk… 0 keine …
## 8 10268 Wil (ZH) 71 1 Zürich 10081 Bezirk… 261 Zürich
## 9 10275 Wettingen 4045 19 Aargau 10025 Bezirk… 4021 Baden …
## 10 10277 Wetzikon … 121 1 Zürich 10079 Bezirk… 261 Zürich
## # … with 2,121 more rows, 48 more variables: HR_AGGL2020 <dbl>,
## # HR_AGGL2020_Name_de <chr>, HR_AGGLGK2012_L1 <dbl>,
## # HR_AGGLGK2012_L1_Name_de <chr>, HR_AGGLGK2012_L2 <dbl>,
## # HR_AGGLGK2012_L2_Name_de <chr>, HR_AGGLGK2020_L1 <dbl>,
## # HR_AGGLGK2020_L1_Name_de <chr>, HR_AGGLGK2020_L2 <dbl>,
## # HR_AGGLGK2020_L2_Name_de <chr>, HR_BAE2018_L1 <chr>,
## # HR_BAE2018_L1_Name_de <chr>, HR_BAE2018_L2 <chr>, …
Acknowledgements
This R package is inspired by swissmuni created by Salim Brüggemann. As swissmuni is available only for the latest version of R and rely on several R package dependencies which are not on CRAN, this R package provides a simplified R wrapper of the API with minimal dependencies so it can be used on older versions of R (R >= 4.0).