如何使用变量填写ggplot shapefile映射?

时间:2019-03-08 22:41:18

标签: r ggplot2 shapefile

我正在尝试填写一张美国地图,在该地图上,每个州均以平均工资(默认色标)填充。我有shapefile和一个看起来像这样的数据框(数据被篡改):

data <- structure(list(State = c("Arkansas",
                           "Iowa",
                           "California",
                           "Idaho"),
                 MeanSalary = c(50000,60000,62000,55000)),
                 row.names=1:4, class = "data.frame")

这是我的代码:

library(tidyverse)
library(rgdal)

map <- readOGR(dsn = ".", layer = "usamap")

PlotData <- merge(map, data, by = "State")

到目前为止,所有这些都有效。我还可以制作一张空地图:

map_base <- ggplot(data = PlotData, mapping=(aes(x=long, y = lat, group = group)) +
geom_polygon(color = "black", fill = NA)
map_base

但是,我无法使用值填写地图。

map_base <- ggplot(data = PlotData, mapping=(aes(x=long, y = lat, group = group)) +
geom_polygon(color = "black", fill = PlotData$MeanSalary)
map_base

我收到此错误:

Error: Aesthetics must be either length 1 or the same as the data (2834334): fill

我怎么了?

1 个答案:

答案 0 :(得分:0)

在这里,我提供了两种使用ggplot2绘制多边形的解决方案。

解决方案1:geom_sf

sf类是R中的下一代空间数据类。geom_sf可以绘制sf对象。为此,我们需要将sp对象转换为sf对象。在这里,我以USAboundaries包中的状态空间多边形为例。

library(tidyverse)
library(sf)
library(USAboundaries)

# Get the state data
state <- us_states()

# Check the class
class(state)
# [1] "sf"         "data.frame"

# Create example data frame
data <- structure(list(State = c("Arkansas",
                                 "Iowa",
                                 "California",
                                 "Idaho"),
                       MeanSalary = c(50000,60000,62000,55000)),
                  row.names=1:4, class = "data.frame")

# Merge data to state and filter for these records
state_filter <- state %>% 
  left_join(data, by = c("name" = "State")) %>%
  # Remove Hawaii, Alaska, and Puerto Rico to just focus on the rest states
  filter(!name %in% c("Hawaii", "Alaska", "Puerto Rico"))

# Plot the data
ggplot(state_filter) +
  geom_sf(aes(fill = MeanSalary))

enter image description here

解决方案2:ggspatial软件包

ggspatial package可以绘制sp对象。因此,如果您不想使用sf对象,则可以选择使用ggspatial

library(tidyverse)
library(sf)
library(USAboundaries)
library(sp)
library(ggspatial)

# Convert the sf object to sp object
state_filter_sp <- as(state_filter, "Spatial")

# Plot the data
ggplot() +
  annotation_spatial(state_filter_sp) +
  layer_spatial(state_filter_sp, aes(fill = MeanSalary))

enter image description here