--- title: "Get started with geopt" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Get started with geopt} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 6, out.width = "100%" ) ``` geopt provides maps of Portugal that are ready to plot, with the Açores and Madeira included, and the tools to put custom data on them. It also keeps track of how the boundaries have changed over the years, and downloads the full-resolution official data when needed. This page is a short tour. Each section points to the guide that covers its topic in full. ```{r setup} library(geopt) ``` ## Portugal's units in brief geopt can draw any of these levels. The `level` value is what its functions expect: | `level` | What it is | Units | |---|---|---| | `"freguesia"` | Civil parish, the smallest administrative unit. | 3 259 | | `"municipio"` | Municipality (município, also called concelho). LAU units | 308 | | `"distrito"` | District on the mainland. Each island in Açores and Madeira | 29 | | `"nuts1"`, `"nuts2"`, `"nuts3"` | The EU's statistical regions (NUTS) | 3, 9, 26 | | `"uls"` | Local health units (Unidades Locais de Saúde) and their island equivalents | 55 | | `"reg_saude"` | Health regions (regiões de saúde) | 7 | | `"aces"` | Groups of primary-care centres (ACES), the health units before 2024 | 71 | | `"uls_municipio"`, `"aces_municipio"` | ULS and ACES for data by municipality: those that share a municipality are combined | 50, 66 | Freguesias and municipalities also have official codes. A freguesia's code (DTMNFR) has six digits: the first four are its municipality's code (DTMN), and the first two are its district's (DT). These are the names DGT and INE use today. Older datasets may call them DICOFRE and DICO. For example, Gualtar, `"030319"`, is a freguesia of Braga municipality (`"0303"`), in Braga district (`"03"`). ## A map in one line ```{r quick-plot} df <- data.frame( concelho = c("Porto","Lisboa","Braga","Coimbra","Faro","Lagoa (Açores)","Santana (RAM)"), score = c(10, 25, 15, 12, 8, 18, 12) ) plot_pt(df, value = "score", by = c(municipio = "concelho")) ``` `by = c(municipio = "concelho")` tells geopt that the `concelho` column holds municipality names. geopt matched each name to its municipality, ignoring accents and case, and picked the right Lagoa: there are two, one in the Algarve and one in the Açores. The islands are moved next to the mainland so the map stays readable. For the mainland alone, add `islands = "none"`. The result is a regular ggplot that can be styled using native `ggplot` grammar. For an interactive map, add `renderer = "echarts"`: ```{r echarts, eval = identical(Sys.getenv("IN_PKGDOWN"), "true")} plot_pt(df, value = "score", by = c(municipio = "concelho"), renderer = "echarts") ``` ## Check what matched When every name is found, matching happens quietly. When some aren't, geopt says so instead of guessing: ```{r check} df <- data.frame( concelho = c("Porto", "Lagoa", "Lisbon"), score = c(10, 18, 25) ) joined <- pt_join(df, by = c(municipio = "concelho")) ``` `pt_join()` adds the official codes to the data frame. `pt_match_report()` then shows what happened to each name: ```{r report} pt_match_report(joined) ``` Two municipalities are called Lagoa, so geopt leaves it unmatched, with the method "ambiguous" rather than pick one. "Lisbon" is an unknown name to geopt, therefore the method shows "unmatched". To solve each of these, specify which Lagoa is meant by providing context - adding "(Açores)" or "(RAA)" to the name - and map the unknown name with `aliases`: ```{r fix} df$concelho[2] <- "Lagoa (Açores)" joined <- pt_join(df, by = c(municipio = "concelho"), aliases = c(Lisbon = "Lisboa")) joined[, c("concelho", "dtmn", "municipio", "nuts3", "reg_saude")] ``` Besides the code, `pt_join()` adds the regions each unit belongs to, which is useful even when no map is drawn. `plot_pt()` and `get_map()` match names the same way, and warn the same way. `vignette("joining-data")` covers joining by code, freguesia names, names from older data, and fuzzy matching for typos. ## Maps as sf objects `plot_pt()` is a shortcut. For more control over the plotting, `get_map()` returns the same map as an sf object, which works with ggplot2, tmap or any other spatial package: ```{r get-map} m <- get_map("nuts3") head(m[, c("nuts3_cod", "nuts3", "area_ha")]) ``` Besides one row per region, the result has a few extra rows for the frames drawn around the islands, marked in the `geopt_type` column. `get_map()` can also join data, with the same `data` and `by` arguments as `plot_pt()`. For boundaries in their true positions, without frames, use `islands = "in_place"`, or the bundled datasets: `pt_freguesias`, `pt_municipios`, `pt_distritos`, `pt_nuts1`, `pt_nuts2`, `pt_nuts3`, `pt_uls`, `pt_reg_saude`, `pt_aces`, `pt_uls_municipio` and `pt_aces_municipio`. `vignette("map-compositions")` shows how to change the island layout and the frames and how to map a single region, such as the Açores, with examples for ggplot2, tmap, echarts4r and plotly. ## Boundaries change over time Portugal's boundaries are redrawn from time to time, and data collected before a change uses the old units. geopt calls each version of a set of boundaries a *vintage*. Three things change, each on its own schedule, so each has its own argument: | What changes | Argument | Vintages | |---|---|---| | Freguesias | `admin_vintage` | `"2001"` and `"2011"` (the 2001 and 2011 censuses), `"2013"`, `"2025"` (current) | | NUTS regions | `nuts_vintage` | `"2002"`, `"2013"`, `"2024"` (current) | | Health regions | `health_vintage` | `"2022"` (before the 2024 reform), `"2024"` (current) | Each `*_vintage` argument is optional: left out, it means the current vintage. Municipalities haven't changed since 1998, so they're the same in every vintage. `pt_lookup()` returns a table of units and the regions they belong to, for the requested vintages. The NUTS regions were revised in 2024. Lisboa and Setúbal are now in different NUTS 2 regions, but until then they shared one: ```{r nuts} now <- pt_lookup("municipio") now[now$municipio %in% c("Lisboa", "Setúbal"), c("municipio", "nuts2_cod", "nuts2")] before <- pt_lookup("municipio", nuts_vintage = "2013") before[before$municipio %in% c("Lisboa", "Setúbal"), c("municipio", "nuts2_cod", "nuts2")] ``` A statistical series published before 2024 uses `PT17`, a code that no longer exists. Names from before a reorganization still match. In 2013, Braga's freguesia of Sé was merged with two others. geopt finds the freguesia that covers it today, and marks the match as `historic`: ```{r historic} pt_match("Sé", level = "freguesia", context = "Braga") ``` `context = "Braga"` says which municipality to look in, since several cities have a freguesia called Sé. `vignette("vintages")` covers converting data between vintages, maps of older years, and NUTS revisions. ## Downloading official data The bundled boundaries are simplified so they plot quickly. geopt can also download official data: census data from INE, the statistics institute, down to the level of city blocks, and the full-resolution official boundaries (CAOP) from DGT, the mapping agency. Downloads are cached, so each file is only fetched once. ```{r downloads, eval = FALSE} # 2021 census data for Braga's statistical sections, with their boundaries braga <- get_censos("Braga", level = "seccao") # Full-resolution municipality boundaries for the mainland client <- GeoClient$new() mun <- client$get_caop("continente", "municipio") ``` `pt_censos_vars` lists the census variables available for each year and level. `vignette("downloading-data")` covers the rest, including filtered queries to DGT's online service. ## Where to go next * **Change the island layout**, draw frames around the islands, or use tmap or echarts4r instead of ggplot2: `vignette("map-compositions")` * **Get data onto the map** by code or by name, including ambiguous and misspelled names: `vignette("joining-data")` * **Map ULS, regiões de saúde or ACES**: `vignette("health-geographies")` * **Work with older boundaries**, or convert freguesia data across reorganizations: `vignette("vintages")` * **Download full-resolution CAOP**, INE census data, or query DGT's online service: `vignette("downloading-data")`