2  Plot map 2022-2025

Objectives

Plot the WPFI country distribution with an interactive map.

2.1 Introduction

Resource 2.1 : Map plotting

I have my notes how to plot maps distributed over several places:

As I am not much experienced with map plotting I am following here closely chapter 9 Making Maps with R respectively chapter 8 of the 2nd edition of the printed book Geocomputation with R (Lovelace, Nowosad, and Muenchow 2025). The text explains mainly the use of {tmap}. I think it is better to know one approach in detail than to have superficial knowledge of several packages. If I have more knowledge and experience in map plotting I will maybe check the other packages to decide which is for my use case the best solution.

During the reading of chapter 9 I will focus to generate a world map with my RBW dataset and skip section that are not relevant for this purpose.

In addition to the example and code demonstrations I will also use my own RWB dataset.

2.2 Prepare WPFI data for colored map

Before I can plot a map with country colors in relation to the press indices I need to join my RWB dataset with the map data from Natural Earth (abbreviated in the code with ne).

R Code 2.1 : Join RWB dataset 2022-2025 with the geometry information of the countries

Run this code chunk manually if the file(s) still needs to be downloaded.
Listing / Output 2.1: Prepare dataset for map plotting by joining RWB data 2022-2025 with country data from Natural Earth
Code
library(dplyr, warn.conflicts = FALSE)
source("R/helper.R")

ne_countries_short <- readRDS(paste0(here::here(), "/data/chap023/ne_countries_short.rds")) |> 
        my_as_tibble_sf()

rwb_2022_2025 <- readRDS(paste0(here::here(), "/data/chap031/rwb_2022_2025.rds"))

rwb_map_2022_2025 <- left_join(
    rwb_2022_2025,
    ne_countries_short,
    by = join_by(iso == adm0_a3)
)

my_save_data_file("chap041", rwb_map_2022_2025, "rwb_map_2022_2025.rds")

(For this R code chunk is no output available)

By inspecting the dataset manually it turned out that for the following countries do exist RWB data but no geometry:

  • OECS: Organisation of Eastern Caribbean States
  • Northern Cyprus
  • Palestine
  • South Sudan
  • Kosovo

I will keep these countries for the and see how their geometry missing is reflected in the world map. If their RWB score will not show up I may delete them from the dataset.

There is another issue with Taiwan (TWN): It has RWB scores and geometry data but is lacking UNSD m49 regional names. The reason is pressure from China which sees Taiwan as one of their provinces. But for my purpose to show the WPFI for as many countries as possible I will add the missing regional names.

R Code 2.2 : Adding regional categories for Taiwan (TWN)

Listing / Output 2.2: Adding regional categories for Taiwan (TWN)
Code
library(dplyr, warn.conflicts = FALSE)
source("R/helper.R")
rwb_map_2022_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2022_2025.rds"))

rwb_map_2022_2025_clean <- rwb_map_2022_2025 |> 
    mutate(
        region = if_else(iso == "TWN", "Asia", region),
        sub_region = if_else(iso == "TWN", "Eastern Asia", sub_region),
        intermediate_region = if_else(iso == "TWN", "Eastern Asia", intermediate_region)
    ) 

my_save_data_file("chap041", rwb_map_2022_2025_clean, "rwb_map_2022_2025_clean.rds")

2.3 Map first draft

R Code 2.3 : Colored WPFI map for 2025 (first)

Code
library(dplyr, warn.conflicts = FALSE)
source("R/helper.R")

rwb_map_2022_2025_clean <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2022_2025_clean.rds"))

rwb_map_2025 <- rwb_map_2022_2025_clean |> 
    dplyr::filter(year == "2025") |> 
    sf::st_as_sf()

my_save_data_file("chap041", rwb_map_2025, "rwb_map_2025.rds")

To inspect the result more in detail I embrace the code with ::: {.column-screen} and ::: to use the whole screen width for the map. After the inspection I will remove this addition and return to the normal view.

R Code 2.4 : Plot the first draft for the choropleth map of the WPFI data 2025

Code
rwb_map_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2025.rds"))

tmap::tm_shape(rwb_map_2025) +             # (1)
tmap::tm_polygons(                         # (2)
    fill = "score",
    fill.legend = tmap::tm_legend(         # (5)
        title = "Global score"
    ),
    fill.scale = tmap::tm_scale_continuous(values = "brewer.blues")
) +
tmap::tm_crs("auto") +                     # (3)
tmap::tm_layout(                           # (4)
    legend.position = c("left","bottom"),
    legend.title.size = 0.8, 
    legend.text.size = 0.5
    ) 
Graph 2.1: Draft 1: World Press Freedom Index 2025 with continuous color palette

In contrast of the original book example I have changed / added several code lines:

  1. tmap::tm_shape(): This is the essential function to start the map plotting and I used it identical as in the book original.
  2. tmap::tm_polygons(): This is the combination of tmap::tm_borders() and tmap::tm_fill().
  3. tmap::tm_crs("auto") was hinted as a console output by the program.
  4. tmap::tm_layout(): This is a function with a huge amount of parameters. I used it here
    • to save space by integrating the legend into the map borders legend.position = c("left","bottom"),
    • to get a smaller text size for the legend title legend.title.size = 0.8,
    • to get a smaller text size for the legend text legend.text.size = 0.5.
  5. fill.legend = tmap::tm_legend(title = "Global score") to change elements inside the legend you need for the current version 4 to provide fill.legend = tmap::tm_legend() inside the appropriate layer. (Version 3 used tmap::tm_legend() as an extra function outside the layer.)

2.4 Map second draft

Note 2.1: Conclusion for fig-041-plot-map-draft1-2025
  • The breaks for the score values do not correspond with the WPFI _situation data.
  • If using the categories for the WPFI _situation data I would need a discrete color palette.

My first draw in fig-041-plot-map-draft1-2025 demonstrate tmap’s default aesthetic settings. Of course, these default values and other aesthetics can be overridden.

  • fill: fill color of a polygon
  • col: color of a polygon border, line, point, or raster
  • lwd: line width
  • lty: line type
  • size: size of a symbol
  • shape: shape of a symbol

Additionally, you may customize the fill and border color transparency using fill_alpha and col_alpha.

For instance, if I would add (col = "white") to the polygon layer I would get white country borders.

fill (and other aesthetics that can vary such as lwd for line layers and size for point layers) will not like base R numbers but requires a character string naming an attribute associated with the geometry to be plotted. Thus, I have achieved the different blue colors using the character string “score” commanding {tmap} to use the content of the appropriate column.

  • If I use instead a factor column like score_situation I will get the country colored with a discrete color palette. See code annotation (6).
  • To correspond the colors with the RWB color scheme in Methdology 2025 I have defined the corresponding colors. See code annotation (7).

R Code 2.5 : Plot the second draft for the choropleth map of the WPFI data 2025

Code
rwb_map_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2025.rds"))

my_colors <- c("seagreen1", "yellow", "gold2", "darkorange", "red3" )

tmap::tm_shape(rwb_map_2025) +             
tmap::tm_polygons(                         
    fill = "score_situation",                                    # (6)
    fill.scale = tmap::tm_scale_categorical(values = my_colors), # (7)
    fill.legend = tmap::tm_legend(title = "Global score")
) +
tmap::tm_crs("auto") +                     
tmap::tm_layout(                           
    legend.position = c("left","bottom"),
    legend.title.size = 0.8, 
    legend.text.size = 0.5
    ) 
Graph 2.2: Draft 2: World Press Freedom Index 2025 with my own discrete color palette

It was difficult to find the solution for the color mapping, because the arguments have changed with version 4 and most of the questions-answers in the internet cover only version 3. After I have used version 3 code I got some hints from the program, but these tips were not immediately conclusive for me. Helpful was the article about tmap charts with the differences between V3 and V4 and the references to the different scales. With the article about Scales: categorical and ordinal scale I finally understand the solution and how to use the value argument hinted in the program message when I used version 3 code.

2.5 Map third draft

Note 2.2

The whole book section on Scales is only partly relevant for me. I have already created own *_situation columns with the break information. I do not need to use the different break arguments for tmap::tm_scales() or styles for the tmap::tm_scale_intervals() or generate my own style with classInt::classIntervals().

For my concrete use case of rwb_map_2025 data I only need to assign color palettes for

In Graph 2.1 and Graph 2.2 I have used a continuous scale for the score column and a categorical scale for the score_situation column. But score_situation is an ordered category.

  • Annotation (8): So let’s try what happens if I use tmap::tm_scale_ordinal().
  • Annotation (9): As the palette has more than five colors, I had to limit the used colors.
  • Annotation (10): I wanted the color palette in reverse (the -sign in front of the palette name), because otherwise you can’t see clearly the few very white countries with good WPFI situations against the huge amount of dark colored countries with very serious condition. As there are several blue palettes I had to use the full palette name.
Note 2.3

I think that the color mapping with the ordinal scale is slightly better than with the continuous scale, where the tiny differences are not always clearly to distinguish.

But maybe it is a good solution to let the user choose which color palette has to be used for the map?

R Code 2.6 : Plot the third draft for the choropleth map of the WPFI data 2025

Code
rwb_map_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2025.rds"))


tmap::tm_shape(rwb_map_2025) +             
tmap::tm_polygons(                         
    fill = "score_situation",                                    
    fill.scale = tmap::tm_scale_ordinal(                       # (8)
        n.max = 5,                                             # (9)
        "-brewer.blues"),                                      # (10)    
    fill.legend = tmap::tm_legend(title = "Global score")
) +
tmap::tm_crs("auto") +                     
tmap::tm_layout(                           
    legend.position = c("left","bottom"),
    legend.title.size = 0.8, 
    legend.text.size = 0.5
    ) 
Graph 2.3: Draft 3: World Press Freedom Index 2025 with a reverse ordered discrete color palette

2.6 Map fourth draft

I could apply as in Graph 2.2 the official color palette. Ssee code annotation (11). In this case the result of Graph 2.4 is similar as in the second trial but now with exact the same colors as described in Methodology of the RWB website.

R Code 2.7 : Plot the fourth draft for the choropleth map of the WPFI data 2025

Code
rwb_map_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2025.rds"))

rwb_colors <- c("#c6e269", "#ecc33d", "#e29950", "#de643a", "#9f1714" ) # (11)

rwb_draft4 <- tmap::tm_shape(rwb_map_2025) +             
tmap::tm_polygons(                         
    fill = "score_situation",                                    
    fill.scale = tmap::tm_scale_ordinal(values = rwb_colors),    # (11)
    fill.legend = tmap::tm_legend(title = "Global score")
) +
tmap::tm_crs("auto") +                     
tmap::tm_layout(                           
    legend.position = c("left","bottom"),
    legend.title.size = 0.8, 
    legend.text.size = 0.5
    )

my_save_data_file("chap041", rwb_draft4, "rwb_draft4.rds")

rwb_draft4
Graph 2.4: Draft 4: World Press Freedom Index 2025 with the official RWB color palette

I have already incorporated the most important changes for the legend. And the layout as a combination of all map elements into a cohesive map are very special and has to be done in the real world Shiny app. When this situation arise then I have to consult the appropriate section of the geocomputation book and especially for turning on the design mode with tmap::tmap_design_mode()my own notes.

2.7 Map fifth draft (facets)

At first I tried the faceted map with the ordered five breaks. But this was a useless decision, because the changes were generally not big enough to change categories. I got four identical facets.

R Code 2.8 : Fifth draft: Faceted map showing the WPFI for the years 2022-2025

Listing / Output 2.3: Faceted map showing the WPFI for the years 2022-2025
Code
library(dplyr, warn.conflicts = FALSE)
source("R/helper.R")

rwb_map_2022_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2022_2025_clean.rds")) |> 
    sf::st_as_sf()

tmap::tm_shape(rwb_map_2022_2025) +             
tmap::tm_polygons(
    fill = "score",                                    
    fill.scale = tmap::tm_scale_continuous(),
    fill.legend = tmap::tm_legend(title = "Global score")
) +
tmap::tm_crs("auto") +                     
  tmap::tm_facets_wrap(by = "year", nrow = 2) +
  tmap::tm_layout(
    legend.orientation = "landscape",
    legend.position = tmap::tm_pos_out(
      cell.h = "center",
      cell.v = "bottom"
    )
  )
Graph 2.5

Therefore I tried it with the continuous scale for the score values as used in Graph 2.1. But again: The small score differences between the four years are not visible because the changes in the color shades are too tiny. If you compare the colors of Argentina in 2022 and 2025 then you will see a substantial deterioration from a 77 to the score of 56. But even with this tremendous difference — where Argentina drops from the rank 29 to the rank 87 — one has difficulty to notice immediately the different color shade.

2.8 Map sixth draft: Facet with a better sequential color palette

R Code 2.9 : Sixth draft: Faceted map showing the WPFI for the years 2022-2025

Listing / Output 2.4: Faceted map showing the WPFI for the years 2022-2025
Code
library(dplyr, warn.conflicts = FALSE)
source("R/helper.R")

rwb_map_2022_2025 <- readRDS(paste0(here::here(), "/data/chap041/rwb_map_2022_2025_clean.rds")) |> 
    sf::st_as_sf()

tmap::tm_shape(rwb_map_2022_2025) +             
tmap::tm_polygons(
    fill = "score",                                    
    fill.scale = tmap::tm_scale_ordinal(
            n.max = 15,
            "carto.ag_sunset"),
    fill.legend = tmap::tm_legend(title = "Global score")
) +
tmap::tm_crs("auto") +                     
  tmap::tm_facets_wrap(by = "year", nrow = 2) +
  tmap::tm_layout(
    legend.orientation = "landscape",
    legend.position = tmap::tm_pos_out(
      cell.h = "center",
      cell.v = "bottom"
    )
  )
#> Warning: Number of levels of the variable assigned to the aesthetic "fill" of
#> the layer "polygons" is 680, which is larger than n.max (which is 15), so
#> levels are combined.
#> [plot mode] fit legend/component: Some legend items or map compoments do not
#> fit well, and are therefore rescaled.
#> ℹ Set the tmap option `component.autoscale = FALSE` to disable rescaling.
Graph 2.6
Note 2.4: Facets only for distinct differences

Even with this more distinctive color palette one cannot see the differences easily. The year-to-year changes are not big enough to get represented in perceptible color shade differences. The use of facets is better suited when the time span between to facets are many years. The book example uses therefore distances of 20 (!) years from one facet to the next.

The same problem applies also with animated map!

Using inset maps could be convenient when the user zooms into part of the maps. The program could zoom for instance into a specific region that the user has chosen via a drop down menu.

2.9 Map seventh draft: Interactivity

A unique feature of {tmap} is its ability to create static and interactive maps using the same code. Maps can be viewed interactively at any point by switching to view mode, using the command tmap::tmap_mode("view").

This should be the same as tmap::tmap_leaflet(data, show = TRUE) with the advantage that you can specify to show or hide the map and that you don’t need to place the code to return to plot mode with tmap::tmap_mode("plot").

R Code 2.10 : Convert object class tmap into interactive leaflet

Run this code chunk manually if the file(s) still needs to be downloaded.
Listing / Output 2.5: Convert tmap into leaflet map
Code
rwb_draft4 <- readRDS(paste0(here::here(), "/data/chap041/rwb_draft4.rds"))
rwb_draft7 <-  tmap::tmap_leaflet(rwb_draft4, show = TRUE)
rwb_draft7

my_save_data_file("chap041", rwb_draft7, "rwb_draft7.rds")
(For this R code chunk is no output available)
Watch out! 2.1: WebGL does not work (yet) with projected map projections

I set warning: false because I got the message

[view mode] WebGL does not work (yet) with projected map projections, so it has been disabled.

Another possibility would have been to use_WebGL = FALSE when calling the tmap::tm_view() function.

2.10 Map eighth draft: Choosing a basemap

Notable features of this interactive mode include the ability to specify the basemap with tmap::tm_basemap() (or tmap::tmap_options()). The first argument of tmap::tm_basemap() is server for obtaining a specific map by a provider. The list of available providers can be obtained with providers (tip: in RStudio, type leaflet::providers$ in the console or in a code chunk to see to see the options). See https://leaflet-extras.github.io/leaflet-providers/preview/ for a preview of those. When a URL is provided, it should be in template format, e.g. https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png. Use NULL in tmap::tm_basemap() to disable basemaps.

Note 2.5

Another basemap layer would not result in a nice visualization as I will color all countries by their score values.

After I have tried to use the OpenTopoMap basemap I got the following warning:

[basemaps] Tiles from “OpenTopoMap” will be projected so details (e.g. text) could appear blurry This message is displayed once per session.

Glossary Entries

term definition
Choropleth A choropleth map is a type of thematic map that uses shading or coloring to represent statistical data across predefined geographic regions. These regions can be political boundaries, such as states or countries, or natural divisions. Each area is colored based on the value of the variable being represented, typically using a gradient where darker shades indicate higher values and lighter shades indicate lower values. This visualization technique helps viewers quickly grasp patterns and trends within the dataset. It is important to note that choropleth maps can sometimes lead to misinterpretation due to the bias introduced by the size of the regions. Larger regions may appear to have more significance simply because of their size, even if their data values are the same as smaller regions. In this case use Cartograms.
M49 The United Nations publication "Standard Country or Area Codes for Statistical Use" was originally published as Series M, No. 49 and is now commonly referred to as the M49 standard. M49 is a country/areas classification system prepared by the Statistics Division of the United Nations Secretariat primarily for use in its publications and databases.
Natural Earth Natural Earth is a public domain map dataset available at 1:10m, 1:50m, and 1:110 million scales. Featuring tightly integrated vector and raster data, with Natural Earth you can make a variety of visually pleasing, well-crafted maps with cartography or GIS software (https://www.naturalearthdata.com/).
OECS The Organisation of Eastern Caribbean States (OECS) is an international inter-governmental organisation dedicated to regional integration in the Eastern Caribbean It was established on June 18, 1981, when seven Eastern Caribbean countries signed the Treaty of Basseterre in St. Kitts and Nevis, aiming to promote cooperation, unity, and solidarity among its members The OECS functions as an economic union, operating a single market and customs union where goods, people, and capital can move freely among its seven protocol member states: Antigua and Barbuda, Commonwealth of Dominica, Grenada, Montserrat, Saint Kitts and Nevis, Saint Lucia, and Saint Vincent and the Grenadines These members are also part of the larger Caribbean Community (CARICOM) and its Caribbean Single Market and Economy (CSME) initiative The organisation's headquarters are located in Castries, Saint Lucia.
RWB Reporters Without Borders (RWB), known by its French name Reporters sans frontières and acronym RSF, is an international non-profit and non-governmental organization headquartered in Paris, France, founded in 1985 in Montpellier by journalists Robert Ménard, Rémy Loury, Jacques Molénat, and Émilien Jubineau. It is dedicated to safeguarding the right to freedom of information and defends journalists and media personnel who are imprisoned, persecuted, or at risk for their work. The organization has consultative status at the United Nations, UNESCO, the Council of Europe, and the International Organisation of the Francophonie.
UNSD The United Nations Statistics Division (UNSD) is committed to the advancement of the global statistical system. It compiles and disseminates global statistical information, develop standards and norms for statistical activities, and support countries' efforts to strengthen their national statistical systems.
WHR The World Happiness Reports are a partnership of Gallup, the Oxford Wellbeing Research Centre, the UN Sustainable Development Solutions Network, and the WHR’s Editorial Board. The report is produced under the editorial control of the WHR Editorial Board. The Reports reflects a worldwide demand for more attention to happiness and well-being as criteria for government policy. It reviews the state of happiness in the world today and shows how the science of happiness explains personal and national variations in happiness. (https://worldhappiness.report/about/)
WPFI The World Press Freedom Index (WPFI) is an annual ranking of countries compiled and published by Reporters Without Borders (RSF), an international non-governmental organization based in France, since 2002. It aims to reflect the degree of freedom that journalists, news organizations, and netizens have in each country, as well as the efforts made by authorities to respect this freedom. The index ranks 180 countries and territories based on RSF's assessment of their press freedom records in the preceding year.

Session Info

Session Info

Code
xfun::session_info()
#> R version 4.5.1 (2025-06-13)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Sequoia 15.6.1
#> 
#> Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8
#> 
#> Package version:
#>   abind_1.4-8             askpass_1.2.1           base64enc_0.1-3        
#>   bslib_0.9.0             cachem_1.1.0            class_7.3-23           
#>   classInt_0.4-11         cli_3.6.5               codetools_0.2-20       
#>   colorspace_2.1-1        cols4all_0.9            commonmark_2.0.0       
#>   compiler_4.5.1          cpp11_0.5.2             crosstalk_1.2.2        
#>   curl_7.0.0              data.table_1.17.8       DBI_1.2.3              
#>   digest_0.6.37           dplyr_1.1.4             e1071_1.7-16           
#>   evaluate_1.0.5          farver_2.1.2            fastmap_1.2.0          
#>   fontawesome_0.5.3       fs_1.6.6                generics_0.1.4         
#>   geojsonsf_2.0.3         geometries_0.2.4        glossary_1.0.0         
#>   glue_1.8.0              graphics_4.5.1          grDevices_4.5.1        
#>   grid_4.5.1              here_1.0.1              highr_0.11             
#>   htmltools_0.5.8.1       htmlwidgets_1.6.4       httpuv_1.6.16          
#>   httr_1.4.7              jquerylib_0.1.4         jsonify_1.2.2          
#>   jsonlite_2.0.0          kableExtra_1.4.0        KernSmooth_2.23-26     
#>   knitr_1.50              labeling_0.4.3          later_1.4.4            
#>   lattice_0.22-7          lazyeval_0.2.2          leafem_0.2.5           
#>   leafgl_0.2.2            leaflegend_1.2.1        leaflet_2.2.2          
#>   leaflet.providers_2.0.0 leafsync_0.1.0          lifecycle_1.0.4        
#>   litedown_0.7            logger_0.4.0            lwgeom_0.2-14          
#>   magrittr_2.0.3          maptiles_0.10.0         markdown_2.0           
#>   MASS_7.3.65             memoise_2.0.1           methods_4.5.1          
#>   mime_0.13               openssl_2.3.3           parallel_4.5.1         
#>   pillar_1.11.0           pkgconfig_2.0.3         png_0.1-8              
#>   promises_1.3.3          proxy_0.4-27            purrr_1.1.0            
#>   R6_2.6.1                rapidjsonr_1.2.0        rappdirs_0.3.3         
#>   raster_3.6-32           RColorBrewer_1.1-3      Rcpp_1.1.0             
#>   renv_1.1.5              rlang_1.1.6             rmarkdown_2.29         
#>   rprojroot_2.1.1         rstudioapi_0.17.1       rversions_2.1.2        
#>   rvest_1.0.5             s2_1.1.9                sass_0.4.10            
#>   scales_1.4.0            selectr_0.4.2           servr_0.32             
#>   sf_1.0-21               sfheaders_0.4.4         slippymath_0.3.1       
#>   sp_2.2-0                spacesXYZ_1.6-0         stars_0.6-8            
#>   stats_4.5.1             stringdist_0.9.15       stringi_1.8.7          
#>   stringr_1.5.1           svglite_2.2.1           sys_3.4.3              
#>   systemfonts_1.2.3       terra_1.8-60            textshaping_1.0.1      
#>   tibble_3.3.0            tidyselect_1.2.1        tinytex_0.57           
#>   tmap_4.1                tmaptools_3.3           tools_4.5.1            
#>   units_0.8-7             utf8_1.2.6              utils_4.5.1            
#>   vctrs_0.6.5             viridisLite_0.4.2       withr_3.0.2            
#>   wk_0.9.4                xfun_0.53               XML_3.99-0.19          
#>   xml2_1.4.0              yaml_2.3.10

References

Felix Analytix. 2023a. “Using r to Map Europe, Asia, Africa, America, Etc.” January. https://www.youtube.com/watch?v=KZcKv3HgzII.
———. 2023b. “How to Map ANY Region of the World Using r Programming.” https://felixanalytix.medium.com/how-to-map-any-region-of-the-world-using-r-programming-bb3c4146f97f.
Lovelace, Robin, Jakub Nowosad, and Jannes Muenchow. 2025. Geocomputation With R. 2nd ed. Boca Raton, FL: Chapman & Hall/CRC.
Wimberly, Michael C. 2022. “Geographic Data Science with R.” [Dataset on Figshare], December. https://doi.org/10.6084/m9.figshare.21301212.v3.
———. 2023a. “Geographic Data Science with r: Visualizing and Analyzing Environmental Change.” https://bookdown.org/mcwimberly/gdswr-book/.
———. 2023b. Geographic Data Science With R: Visualizing and Analyzing Environmental Change. 1st ed. Boca Raton, FL: Chapman & Hall/CRC.