我正在使用栅格包中的getData函数来检索阿根廷的地图。我想使用ggplot2绘制生成的地图,所以我使用扫帚包中的tidy函数转换为数据帧。这很好,但我无法弄清楚如何保留联邦区的名称,以便我可以在地图上使用它们。
这是我的原始代码,不保留地区名称:
# Original code: ##################################
# get the map data from GADM.org and then simplify it
arg_map_1 <- raster::getData(country = "ARG", level = 1, path = "./data/") %>%
# simplify
rmapshaper::ms_simplify(keep = 0.01) %>%
# tidy to a dataframe
broom::tidy()
# plot the map
library(ggplot2)
ggplot(data=arg_map_1) +
geom_map(map=arg_map_1, aes(x=long, y=lat, map_id=id, fill=id),
color="#000000", size=0.25)
这是带有hack的代码,可以将区域名称从SPDF中提取出来并将它们用作地图ID:
# Code with a hack to keep the district names: ################################
# get the map data from GADM.org and then simplify it
arg_map_1 <- raster::getData(country = "ARG", level = 1, path = "./data/") %>%
# simplify
rmapshaper::ms_simplify(keep = 0.01)
for(region_looper in seq_along(arg_map_1@data$NAME_1)){
arg_map_1@polygons[[region_looper]]@ID <-
as.character(arg_map_1@data$NAME_1[region_looper])
}
# tidy to a dataframe
arg_map_1 <- arg_map_1 %>%
broom::tidy()
library(ggplot2)
ggplot(data=arg_map_1) +
geom_map(map=arg_map_1, aes(x=long, y=lat, map_id=id, fill=id),
color="#000000", size=0.25)
我一直认为必须有某种方法来使用保留名字的整洁功能,但对于我的生活,我无法弄明白。
答案 0 :(得分:3)
您可以使用包join
中的plyr
功能。这是一个通用的解决方案(看起来很长但实际上非常简单):
加载shapefile :我们假设您的工作目录中有shapefile my_shapefile.shp
。我们加载吧:
shape <- readOGR(dsn = "/my_working_directory", layer = "my_shapefile")
请注意,在此shapefile中有一个数据框,可以使用shape@data
进行访问。例如,此数据框可能如下所示:
> head(shape@data)
code region label
0 E12000006 East of England E12000006
1 E12000007 London E12000007
2 E12000002 North West E12000002
3 E12000001 North East E12000001
4 E12000004 East Midlands E12000004
5 E12000003 Yorkshire and The Humber E12000003
从shapefile创建新数据框:使用broom
包来填充shapefile数据框:
new_df <- tidy(shape)
这导致如下:
> head(new_df)
long lat order hole piece group id
1 547491.0 193549.0 1 FALSE 1 0.1 0
2 547472.1 193465.5 2 FALSE 1 0.1 0
3 547458.6 193458.2 3 FALSE 1 0.1 0
4 547455.6 193456.7 4 FALSE 1 0.1 0
5 547451.2 193454.3 5 FALSE 1 0.1 0
6 547447.5 193451.4 6 FALSE 1 0.1 0
不幸的是,tidy()
丢失了变量名称(在本例中为“region”)。相反,我们得到一个新变量“id”,从0开始。幸运的是,“id”的顺序与shape@data$region
中存储的顺序相同。让我们用它来恢复名称。
使用行名创建辅助数据框:让我们创建一个包含行名的新数据框。另外,我们将添加一个“id”变量,与创建的tidy()
相同:
# Recover row name
temp_df <- data.frame(shape@data$region)
names(temp_df) <- c("region")
# Create and append "id"
temp_df$id <- seq(0,nrow(temp_df)-1)
使用“id”将行名称与新数据框合并:最后,让我们将名称放回新的数据框中:
new_df <- join(new_df, temp_df, by="id")
就是这样!您甚至可以使用join
命令和“id”索引向新数据帧添加更多变量。最终的结果将是:
> head(new_df)
long lat order hole piece group id name var1 var2
1 547491.0 193549.0 1 FALSE 1 0.1 0 East of England 0.525 0.333
2 547472.1 193465.5 2 FALSE 1 0.1 0 East of England 0.525 0.333
3 547458.6 193458.2 3 FALSE 1 0.1 0 East of England 0.525 0.333
4 547455.6 193456.7 4 FALSE 1 0.1 0 East of England 0.525 0.333
5 547451.2 193454.3 5 FALSE 1 0.1 0 East of England 0.525 0.333
6 547447.5 193451.4 6 FALSE 1 0.1 0 East of England 0.525 0.333
答案 1 :(得分:2)
alistaire的评论促使我继续推动region=
参数。我尝试了很多迭代,我在这个帖子https://github.com/tidyverse/ggplot2/issues/1447中找到了一些想法。
以下是抓取地区名称的代码:
# load the magrittr library to get the pipe
library(magrittr)
# load the maptools library to get the rgeos object
library(maptools)
arg_map_1 <- raster::getData(country = "ARG", level = 1, path = "./data/") %>%
# simplify
rmapshaper::ms_simplify(keep = 0.01) %>%
# tidy to a dataframe
broom::tidy(region="NAME_1")
# plot the map
library(ggplot2)
ggplot(data=arg_map_1) +
geom_map(map=arg_map_1, aes(x=long, y=lat, map_id=id, fill=id),
color="#000000", size=0.25)
首先,请注意必须加载maptools库才能使整洁操作正常工作。另外,我想强调一下,从中提取区域信息的变量必须用引号括起来。我一直错误地认为扫帚会识别变量名称的方式与dplyr等其他tidyverse软件包识别未加引号或被反引号包围的列名相同。