R 语言社区有不少 R 包涉及中国地图数据,但是质量不一,比如maps(Brownrigg 2021)和mapdata包(Richard A. Becker and Ray Brownrigg. 2018)内置的中国地图,精度不够也不完整。下面先简单介绍下几个主要的数据源及其质量情况,最后以湖南省邵阳市各个区县的近5年人口增长率数据为例,介绍交互地图绘制方法,也是笔者比较推荐的绘图姿势。
矢量数据
早年统计之都有篇文章介绍用 R 软件绘制中国分省市地图,现将几种方法简单回顾下,部分代码有现代化改造。
maps 包
利用 maps 包内置的世界地图,获取中国的边界,缺少台湾和南海岛屿。
library(maps)
map(
database = "world", regions = "china",
col = "red4", xlim = c(72, 137), panel.first = grid()
)
mapdata 包
加载 mapdata 包,有份内置的中国分省的地图数据,但是缺少重庆市。
library(mapdata)
map(
database = "china",
col = "red4", xlim = c(72, 137), panel.first = grid()
)
用 ggplot2 包绘制地图也不难,几行代码:
library(ggplot2)
china_map <- map(database = "china", plot = F)
ggplot() +
geom_path(
data = china_map, aes(long, lat, group = group),
color = "#FD9FA4", show.legend = F
) +
coord_map(projection = "mercator")
统计之都网站
从国家基础地理信息中心的网站 http://nfgis.nsdi.gov.cn/ 下载 GIS 数据,目前此网站已经不可用,统计之都提供了数据下载地址。下载保存到本地解压后,可采用 sf 包(Pebesma 2018)绘制地图4。历史原因数据比较久远了,不推荐使用。
library(sf)
# Linking to GEOS 3.10.2, GDAL 3.4.2, PROJ 8.2.1; sf_use_s2() is TRUE
china <- read_sf("data/china-province-border-data/bou2_4p.shp", as_tibble = FALSE)
# 将 NAME 列转码
china$NAME <- iconv(china$NAME, from = "CP936", to = "UTF-8")
# 设置坐标参考系
st_crs(china) <- 4326
# 绘图
plot(china["NAME"], main = "")
Natural Earth 网站
rnaturalearth (South 2017)和 rnaturalearthdata 提供国家地理网站的 R 语言接口,可以免费下载矢量和栅格地图数据。精度稍高一点的地图数据需要下载rnaturalearthhires 包,它有 20 多 M,不在 CRAN 上,安装命令如下:
install.packages(
pkgs = "rnaturalearthhires",
repos = "http://packages.ropensci.org",
type = "source"
)
## 加载 R 包
library(rnaturalearth)
library(rnaturalearthdata)
下载数据,调用 sf 包绘制中国地图数据,如图5。
# 中国大陆地区
chn_map <- rnaturalearth::ne_countries(
country = "China",
continent = "Asia",
type = "countries",
scale = 10, returnclass = "sf"
)
# 台湾地区
twn_map <- rnaturalearth::ne_countries(
country = "Taiwan",
continent = "Asia",
type = "countries",
scale = 10, returnclass = "sf"
)
# 绘制地图
plot(st_geometry(chn_map))
plot(st_geometry(twn_map), add = TRUE)
这个地图数据有些明显的问题,将台湾地区的数据和中国分离开,南海诸岛的数据缺失很多,关于地图,这是一点都不能少的!笔者在国家地理网站的声明里了解到,地区边界是根据实际控制划分的。
GADM 网站
raster 包(Hijmans 2022a)可以免费下载网站GADM上的国家行政边界信息,可以用作学术和非商业用途。提供国家级、省级、市级和区县级行政边界数据,可以直接下载并导入 R 环境,读者可根据需要,下载 sp 或 sf 类型的数据对象。
library(sf)
# 下载中国区县级行政地图
# raster::getData('ISO3') 各个国家或地区的 ISO3 代码
china_map <- raster::getData(
name = "GADM",
country = "CHN", # 中国的 ISO3 代码
level = 3, # 国家=0 省=1 市=2 县=3
type = "sf", # 返回数据类型为 sf 类型
path = "~/data/" # 保存到本地目录,以便复用
)
china_map
# Simple feature collection with 2408 features and 16 fields
# Geometry type: MULTIPOLYGON
# Dimension: XY
# Bounding box: xmin: 73.56 ymin: 18.16 xmax: 134.8 ymax: 53.56
# old-style crs object detected; please recreate object with a recent sf::st_crs()
# Geodetic CRS: WGS 84
# First 10 features:
# old-style crs object detected; please recreate object with a recent sf::st_crs()
# old-style crs object detected; please recreate object with a recent sf::st_crs()
# GID_0 NAME_0 GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2
# 185838 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185818 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185767 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185912 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185835 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185720 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185913 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185740 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185763 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.1_1 Anqing 安庆市
# 185270 CHN China CHN.1_1 Anhui 安徽|安徽 CHN.1.2_1 Bengbu 蚌埠市
# GID_3 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3
# 185838 CHN.1.1.1_1 Anqing <NA> <NA> Xiànjíshì County City <NA>
# 185818 CHN.1.1.2_1 Huaining Huáiníng 怀宁县 Xiàn County <NA>
# 185767 CHN.1.1.3_1 Qianshan Qiánshān 潜山县 Xiàn County <NA>
# 185912 CHN.1.1.4_1 Susong Sùsōng 宿松县 Xiàn County <NA>
# 185835 CHN.1.1.5_1 Taihu Tàihú 太湖县 Xiàn County <NA>
# 185720 CHN.1.1.6_1 Tongcheng Tóngchéng 桐城市 Xiànjíshì County City <NA>
# 185913 CHN.1.1.7_1 Wangjiang Wàngjiāng 望江县 Xiàn County <NA>
# 185740 CHN.1.1.8_1 Yuexi Yuèxī 岳西县 Xiàn County <NA>
# 185763 CHN.1.1.9_1 Zongyang Zōngyáng 枞阳县 Xiàn County <NA>
# 185270 CHN.1.2.1_1 Bengbu <NA> <NA> Xiànjíshì County City <NA>
# HASC_3 geometry
# 185838 <NA> MULTIPOLYGON (((117.2 30.63...
# 185818 <NA> MULTIPOLYGON (((116.5 30.38...
# 185767 <NA> MULTIPOLYGON (((116.5 30.46...
# 185912 <NA> MULTIPOLYGON (((116.6 30.05...
# 185835 <NA> MULTIPOLYGON (((116.5 30.38...
# 185720 <NA> MULTIPOLYGON (((117.1 31.07...
# 185913 <NA> MULTIPOLYGON (((116.7 30.06...
# 185740 <NA> MULTIPOLYGON (((116.2 30.66...
# 185763 <NA> MULTIPOLYGON (((117.1 31.07...
# 185270 <NA> MULTIPOLYGON (((117.3 32.83...
st_crs(china_map) <- 4326
# old-style crs object detected; please recreate object with a recent sf::st_crs()
下面提取湖南省邵阳市下辖的各个区县的地图数据,绘制行政区划图。
shaoyang_map <- china_map[china_map$NAME_1 == "Hunan" & china_map$NAME_2 == "Shaoyang", ]
plot(shaoyang_map["NAME_3"], main = "", key.pos = NULL)
中国民政部网站
中华人民共和国民政部提供了中国地图数据,是 GeoJSON 格式的,属于权威数据源,推荐使用。笔者最早是从统计之都论坛上得知的。离散空间数据常见的形式有点、线和多边形,点数据就不用多说了,线数据的典型例子就是北京地铁线路图,而多边形数据的典型例子是各级行政区划图。
library(sf)
china_map <- st_read(dsn = "data/mca/quanguo_Line.geojson", stringsAsFactors = FALSE)
# Reading layer `线' from data source
# `/Users/xiangyun/Documents/xiangyun/content/post/2022-02-09-draw-china-maps/data/mca/quanguo_Line.geojson'
# using driver `GeoJSON'
# Simple feature collection with 104 features and 3 fields
# Geometry type: LINESTRING
# Dimension: XY
# Bounding box: xmin: 73.68 ymin: 3.554 xmax: 135.2 ymax: 53.65
# Geodetic CRS: WGS 84
china_map
# Simple feature collection with 104 features and 3 fields
# Geometry type: LINESTRING
# Dimension: XY
# Bounding box: xmin: 73.68 ymin: 3.554 xmax: 135.2 ymax: 53.65
# Geodetic CRS: WGS 84
# First 10 features:
# NAME QUHUADAIMA strZTValue geometry
# 1 hainansheng LINESTRING (121.9 30.84, 12...
# 2 hainansheng LINESTRING (121.4 30.82, 12...
# 3 hainansheng LINESTRING (121.5 31.64, 12...
# 4 tiaohuijie LINESTRING (124.4 40.08, 12...
# 5 tiaohuijie LINESTRING (124.5 40.13, 12...
# 6 台湾岛 daoyu6 LINESTRING (121.4 22.46, 12...
# 7 海南岛 daoyu5 LINESTRING (111.5 19, 112.4...
# 8 钓鱼岛 daoyu6 LINESTRING (122.8 26.07, 12...
# 9 赤尾屿 daoyu6 LINESTRING (125.2 25.86, 12...
# 10 黄岩岛 daoyu6 LINESTRING (117.2 14.61, 11...
plot(china_map)
另一份地图数据是全国各省的行政区域,如果读者有各个省的数据,比如人口增长率、人均GDP等,可以利用上此地图数据。
china_map <- st_read(dsn = "data/mca/quanguo.json", stringsAsFactors = FALSE, crs = st_crs(4326))
# Reading layer `quanguo' from data source
# `/Users/xiangyun/Documents/xiangyun/content/post/2022-02-09-draw-china-maps/data/mca/quanguo.json'
# using driver `TopoJSON'
# Simple feature collection with 156 features and 4 fields
# Geometry type: POLYGON
# Dimension: XY
# Bounding box: xmin: 73.68 ymin: 3.984 xmax: 135.2 ymax: 53.65
# Geodetic CRS: WGS 84
china_map
# Simple feature collection with 156 features and 4 fields
# Geometry type: POLYGON
# Dimension: XY
# Bounding box: xmin: 73.68 ymin: 3.984 xmax: 135.2 ymax: 53.65
# Geodetic CRS: WGS 84
# First 10 features:
# id NAME QUHUADAIMA FillColor geometry
# 1 <NA> 710000 daodian POLYGON ((119.6 23.51, 119....
# 2 <NA> 440000 daodian POLYGON ((116.8 20.85, 116....
# 3 <NA> 710000 daodian POLYGON ((119.7 23.69, 119....
# 4 <NA> 710000 daodian POLYGON ((119.5 23.32, 119....
# 5 <NA> 460000 daodian POLYGON ((111.6 17.22, 111....
# 6 <NA> 460000 daodian POLYGON ((112.7 5.657, 112....
# 7 <NA> 460000 daodian POLYGON ((112.6 5.911, 112....
# 8 <NA> 460000 daodian POLYGON ((112.6 6.092, 112....
# 9 <NA> 460000 daodian POLYGON ((112.7 5.233, 112....
# 10 <NA> 460000 daodian POLYGON ((113.3 6.475, 113....
plot(china_map["QUHUADAIMA"])
海拔数据
下面再看看The NASA Shuttle Radar Topographic Mission (SRTM)提供的地形数据,以海拔数据为例,采用 raster 包(Hijmans 2022a)下载数据,terra 包(Hijmans 2022b)来绘制地图。相比于 raster 包,terra 性能好得多,读者不妨试试用 raster 包来绘制中国地形地图。
# 创建目录存储海拔地形数据
xfun::dir_create("~/data/")
# [1] TRUE
# 下载数据
# 中国大陆地区
chn_map <- raster::getData(name = "alt", country = "CHN", mask = TRUE, path = "~/data/")
# 台湾地区
twn_map <- raster::getData(name = "alt", country = "TWN", mask = TRUE, path = "~/data/")
# 香港地区
hkg_map <- raster::getData(name = "alt", country = "HKG", mask = TRUE, path = "~/data/")
# 澳门地区
mac_map <- raster::getData(name = "alt", country = "MAC", mask = TRUE, path = "~/data/")
# 转化为 SpatRaster 类型
chn_map <- terra::rast(x = chn_map * 1)
twn_map <- terra::rast(x = twn_map * 1)
hkg_map <- terra::rast(x = hkg_map * 1)
mac_map <- terra::rast(x = mac_map * 1)
# 合并 SpatRaster 数据
china_map <- terra::merge(chn_map, twn_map, hkg_map, mac_map)
# 查看数据类型
china_map
# class : SpatRaster
# dimensions : 4272, 7368, 1 (nrow, ncol, nlyr)
# resolution : 0.008333, 0.008333 (x, y)
# extent : 73.5, 134.9, 18.1, 53.7 (xmin, xmax, ymin, ymax)
# coord. ref. : +proj=longlat +datum=WGS84 +no_defs
# source : memory
# name : CHN_msk_alt
# min value : -156
# max value : 8685
中国地域辽阔,海拔地形数据 CHN_msk_alt.gri
有 60 M,调 terra 包绘图速度快。
terra::plot(china_map,
range = c(-1000, 9000), # 海拔范围
col = terrain.colors(20, rev = FALSE), # 海拔划分 20 个区间
mar = c(2, 2, 1, 3.75), # 图形边空
plg = list(
at = 1000 * 0:8, # 图例刻度位置
legend = 1000 * 0:8 # 图例刻度文本
)
)
瓦片地图
OpenStreetMap 地图
本节主要采用 leaflet 包(Cheng, Karambelkar, and Xie 2022)绘制交互地图,leaflet 包默认调用的地图数据服务来自 OpenStreetMap。leaflet 包的 leaflet::addTiles()
函数默认提供了开放街道瓦片地图服务,
leafletCN 包的 leafletCN::amap()
函数封装了高德瓦片地图服务的 URL 模版。实际上,只要提供瓦片服务的 URL 模版,就可以将 leaflet 服务替换成任意其他地图服务。如图11在谷歌地图上展示「中国矿业大学(北京)」学院路校区。
# 谷歌瓦片地图服务
library(leaflet)
leaflet() |>
addTiles(urlTemplate = "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}") |>
setView(116.347817690225, 39.997202126977, zoom = 16) |>
addMarkers(116.347817690225, 39.997202126977)
高德地图
leafletCN(Lang 2017) 包内置一部分中国省、市边界地图数据,支持调用高德瓦片地图服务,提供部分合规的中国地图,核心函数是 geojsonMap()
,它封装了 GeoJSON 格式的地图数据和绘图功能,更多定制参考leaflet::leaflet()
。
只要数据包含的一列区域名称和地图数据能映射上,就可以绘制出图12,图中数据是随机生成的,调色板采用 RdBu
,将连续的数据分段,每段对应一个色块。
library(leaflet)
library(leafletCN) # 提供 geojsonMap 函数
dat <- data.frame(name = regionNames("china"), value = runif(34))
# 还有很多其他参数设置,类似 leaflet::leaflet
geojsonMap(dat, mapName = "china", palette = "RdBu", colorMethod = "bin")
绘制某个省份、直辖市、地级市的数据,图13和图14分别展示北京市、邵阳市下各个区县的数据。不难发现,leafletCN 包内置的地图边界和名称等数据尚未更新,下图13还是崇文、宣武区,实际它们已经合并至东、西城区,图14还是邵东县,实际已经升级为邵东市,是由邵阳市代管的县级市。
dat <- data.frame(name = regionNames("北京"), value = runif(18))
geojsonMap(dat, mapName = "北京", palette = "RdBu", colorMethod = "bin")
dat <- data.frame(name = regionNames("邵阳"), value = runif(12))
geojsonMap(dat, mapName = "邵阳", palette = "RdBu", colorMethod = "bin")
可见,市和区县级地图边界数据是存在问题的,省级边界地图数据配合高德提供的背景地图数据是基本可用。一个更可靠的方式是不要使用此边界数据,只使用高德地图,以气泡图代替,类似图15,要点是需要准备各个区县级以上城市的经纬度坐标,并且和高德地图采用的坐标系是一致的,这样气泡的位置和地图上显示的城市名称是基本重合的。
另一个解决办法的使用阿里 DataV 数据可视化平台开放出来的地图数据,它来自高德开放平台。下载到本地保存为文件邵阳市.json
,检查后,发现地图数据的参考系是 WGS 84,这和 OpenStreetMap 所要求的坐标系正好一致,下面就采用 leaflet 包来绘制。以邵阳市地区的数据为例,从邵阳市统计局发布的统计年鉴获取2010年、2015年和2020年邵阳市各个区县的人口数(单位:万人)。邵阳市各个区县近5年和近10年的人口增长率,如图16所示,邵东市近5年的人口呈负增长,笔者在图上还补充了很多数据信息,供读者参考。如果能够收集到全国所有区县级城市的人口数据,还可以发现中国各个经济带的地域差异,沿海内陆差异,南北差异等一系列有用的信息,如洞悉人口流动的方向。
library(leaflet)
library(sf)
# 读取 GeoJSON 格式的多边形矢量地图数据
shaoyang_map <- sf::read_sf("data/中国地图/湖南省/邵阳市.json")
# 添加 2020年、2015年和2010年邵阳市各个区县的人口数(单位:万人)
shaoyang_data <- tibble::tribble(
~adcode, ~name2, ~pop20, ~pop10, ~pop15,
430502, "双清区", 26.76, 27.97, 27.82,
430503, "大祥区", 32.05, 32.16, 32.52,
430511, "北塔区", 10.21, 9.06, 9.72,
430522, "新邵县", 82.04, 80.4, 82.81,
430523, "邵阳县", 105.82, 103.62, 104.82,
430524, "隆回县", 129.41, 120.31, 126.29,
430525, "洞口县", 89.53, 84.66, 88.1,
430527, "绥宁县", 38.29, 37.55, 38.39,
430528, "新宁县", 64.52, 61.67, 64.97,
430529, "城步苗族自治县", 27.95, 27.32, 27.6,
430581, "武冈市", 82.69, 81.12, 84.13,
430582, "邵东市", 133.06, 128.13, 133.59
)
# 近 5 年人口增长率
shaoyang_data <- transform(shaoyang_data, pop = (pop20 - pop15) / pop15)
# sf 转化为数据框
shaoyang_map <- as.data.frame(shaoyang_map)
# 观测数据和地图数据按行政区划编码合并
shaoyang <- merge(shaoyang_map, shaoyang_data, by = "adcode")
# 数据框转化为 sf
shaoyang <- sf::st_as_sf(shaoyang, sf_column_name = "geometry")
# 可以设置分段离散的调色板
# pal <- colorBin("Spectral", bins = pretty(shaoyang$pop), reverse = TRUE)
pal <- colorNumeric("Spectral", domain = NULL)
# 将数据绘制到地图上
leaflet(shaoyang) |>
addTiles(
# 来自 leafletCN::amap()
urlTemplate = "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
options = tileOptions(tileSize = 256, minZoom = 3, maxZoom = 17),
attribution = "© <a href=\"http://amap.com\">amp.com</a >"
) |>
addPolygons(
stroke = F, # 不显示各个区县的边界线
weight = 1, # 设置边界线宽度
fillOpacity = 0.7, # 填充多边形的透明度
fillColor = ~ pal(pop),
label = lapply(paste0(
"城市:", "<b>", shaoyang$name, "</b>", "<br/>",
"5年人口增长率:", sprintf("%.3f%%", 100 * (shaoyang$pop20 - shaoyang$pop15) / shaoyang$pop15), "<br/>",
"10年人口增长率:", sprintf("%.3f%%", 100 * (shaoyang$pop20 - shaoyang$pop10) / shaoyang$pop10)
), htmltools::HTML),
popup = ~ paste0(
"城市:", name, "<br/>",
"<hr/>",
"2020年人口:", pop20, "(万)", "<br/>",
"2015年人口:", pop15, "(万)", "<br/>",
"2010年人口:", pop10, "(万)", "<br/>",
"10年人口增长率:", sprintf("%.2f%%", 100 * (pop20 - pop10) / pop10), "<br/>",
"10年间平均每年增加人口:", format((pop20 - pop10) / 10, digit = 4), "(万)", "<br/>"
)
) |>
addLegend(
position = "bottomright", title = "5年人口增长率",
pal = pal, values = ~pop, opacity = 1.0,
labFormat = labelFormat(
suffix = "%",
transform = function(x) round(100 * x, digits = 2)
)
) |>
addScaleBar(position = "bottomleft")
收集全国各个区县的数据指标后,需要先将每个市的区县级地图数据合并,然后以各个区县的国家行政编码作为唯一主键,将数据指标和地图数据合并,再映射到地图上,一张信息量更为丰富的专题地图就画出来了。首先下载各省各地级市区县级地图数据,为方便管理和使用,仍然按省组织,文件存储目录如下:
data
└── 中国地图
├── 江西省
│ └── 南昌市.json
└── 湖南省
├── 娄底市.json
├── 邵阳市.json
└── 长沙市.json
接下来是批量地将数据导入 R 环境,并组合成全国区县级地图数据,下面仍以两省四市的数据为例。
library(sf)
# 批量读取数据
map_list <- lapply(
X = list.files("data/中国地图", recursive = T, full.names = T),
FUN = sf::read_sf
)
# 合并各个市的数据
china_map <- Reduce("rbind", map_list)
# 使用 Base R 绘图
plot(china_map["name"], main = "")
也可用 ggplot2 包来绘制
library(ggplot2)
ggplot(data = china_map) +
geom_sf()
Highcharts 地图
另一个提供地图数据的是商业软件 Highcharts Maps,国内外有不少商业公司是它的客户,它也有一个 R 包highcharter,有一个以美国地图数据为背景的博客详细介绍了使用过程,详见 Highcharts 官方博客。简数科技 定制了一份 GeoJSON 格式的中国地图数据,还提供了地图预览和下载的服务,因为涉及商业版权和地图数据合规性,使用需要注意,读者可前往网站了解。另一个 R 包hchinamap 也是使用这份中国地图数据和 JavaScript 库 Highcharts JS。
library(hchinamap)
# name 是地图数据中的各个区域单元的名称
hchinamap(
name = c("北京", "天津", "上海", "湖南", "台湾", "海南"),
value = c(120, 200, 126, 300, 150, 225),
width = "100%",
height = "650px",
title = "分省地图",
region = "China",
minColor = "#f1eef6",
maxColor = "#980043",
itermName = "指标",
hoverColor = "#f6acf5"
)
环境信息
本文的 R Markdown 源文件是在 RStudio IDE 内编辑的,用 blogdown (Xie, Hill, and Thomas 2017) 构建网站,Hugo 渲染 knitr 之后的 Markdown 文件,得益于 blogdown 对 R Markdown 格式的支持,图、表和参考文献的交叉引用非常方便,省了不少文字编辑功夫。文中使用了多个 R 包,为方便复现本文内容,下面列出详细的环境信息:
xfun::session_info(packages = c(
"knitr", "rmarkdown", "blogdown",
"ggplot2", "leaflet", "lattice",
"sp", "raster", "sf", "terra",
"maps", "mapdata", "mapproj",
"rnaturalearth", "rnaturalearthdata"
), dependencies = FALSE)
# R version 4.2.0 (2022-04-22)
# Platform: x86_64-apple-darwin17.0 (64-bit)
# Running under: macOS Big Sur/Monterey 10.16
#
# Locale: en_US.UTF-8 / en_US.UTF-8 / en_US.UTF-8 / C / en_US.UTF-8 / en_US.UTF-8
#
# Package version:
# blogdown_1.10 ggplot2_3.3.6 knitr_1.39
# lattice_0.20-45 leaflet_2.1.1 mapdata_2.3.0
# mapproj_1.2.8 maps_3.4.0 raster_3.5-15
# rmarkdown_2.14 rnaturalearth_0.1.0 rnaturalearthdata_0.1.0
# sf_1.0-7 sp_1.4-7 terra_1.5-21
#
# Pandoc version: 2.18
#
# Hugo version: 0.98.0