如何在地图上标记单个状态,而其他状态在分区级别

How to label an individual state on the map while the others at sub-divisional level

我已经制作了一张地图,但是我需要为包含细分(级别 3)的州(级别 2)添加一个标签,而不是标记每个细分(仅针对该州)。在数据"newpak"中第641-664行对应这个州,有没有办法只在这个州上面放一个名字

library(dplyr)
library(raster)
library(sf)
library(tidyverse)
library(ggrepel)
devtools::install_github("tidyverse/ggplot2", force = TRUE)
library(ggplot2)

pak <- getData("GADM",country="PAK",level=3) 

pak <- st_as_sf(pak) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]]))

ggplot(pak) + geom_sf() + geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2)

ind <- getData("GADM",country="IND",level=3) 

ind <- st_as_sf(ind) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]]))

jnk <- subset(ind, OBJECTID >= 641 & OBJECTID <= 664 )

newpak <- rbind(pak, jnk)


regionalValues <- runif(165)  # Simulate a value for each region between 0 and 1

ggplot(newpak) + geom_sf(aes(fill = regionalValues)) + geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2)

这是使用 sf 包的完整解决方案。

library(raster)
library(sf)
library(tidyverse)

# downlaod PAK data and convert to sf
pak <- getData("GADM",country="PAK",level=3) %>% 
  st_as_sf()

# download IND data, convert to sf, filter out 
# desired area, and add NAME_3 label
jnk <- getData("GADM",country="IND",level=3) %>%
  st_as_sf() %>%
  filter(OBJECTID %>% between(641, 664)) %>%
  group_by(NAME_0) %>%
  summarize() %>%
  mutate(NAME_3 = "Put desired region name here")


regionalValues <- runif(142)  # Simulate a value for each region between 0 and 1

# combine the two dataframes, find the center for each
# region, and the plot with ggplot
pak %>% 
  select(NAME_0, NAME_3, geometry) %>%
  rbind(jnk) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]])
    ) %>%
  ggplot() + 
  geom_sf(aes(fill = regionalValues)) +
  geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2) +
  scale_fill_distiller(palette = "Spectral")

一些注意事项:

  • 我使用 sf::filter 而不是 raster::subset 来获取所需的 IND 数据子集,因为我觉得它更符合惯用的 tidyverse 代码。

  • 要使用 sf 组合区域,您可以使用 group_by 将不同区域分组为一个公共组,然后只需调用 summarize。这是我在上面的解决方案中使用的方法。 sf 包中还有其他函数可以实现类似的结果,值得一看。它们是 st_combinest_union

  • 使用 st_centroid 来绘制区域标签不一定是找到区域标签的最佳位置的最佳方法。我用它是因为它最方便。您可以尝试其他方法,包括手动放置标签。

  • 我将填充调色板更改为发散调色板,因为我认为它更清楚地显示了一个区域与下一个区域之间的差异。您可以看到一些可用的调色板 RColorBrewer::display.brewer.all()