R ggplot2与shapefile和csv数据合并以填充多边形

R ggplot2与shapefile和csv数据合并以填充多边形,r,merge,ggplot2,R,Merge,Ggplot2,我们每天制作地图,显示我们地区30个不同区域的计算温度水平,每个区域根据不同的水平用不同的颜色填充。这张地图看起来像 现在我想将地图生成切换到R。我已经下载了省级和市级边界(您可以在这里找到或找到),并按照哈德利的方法使用ggplot2绘制了它们 我还可以生成一个包含两列的ascii文件:标识符(CODINE)和每日级别。你可以下载 这是我第一个尝试用R和ggplot2绘制形状文件的脚本,所以可能会有错误,当然可以改进,欢迎您的建议。以下代码(基于Hadley之前提到的代码)对我很有用: &g

我们每天制作地图,显示我们地区30个不同区域的计算温度水平,每个区域根据不同的水平用不同的颜色填充。这张地图看起来像

现在我想将地图生成切换到R。我已经下载了省级和市级边界(您可以在这里找到或找到),并按照哈德利的方法使用ggplot2绘制了它们

我还可以生成一个包含两列的ascii文件:标识符(CODINE)和每日级别。你可以下载

这是我第一个尝试用R和ggplot2绘制形状文件的脚本,所以可能会有错误,当然可以改进,欢迎您的建议。以下代码(基于Hadley之前提到的代码)对我很有用:

> require("rgdal")
> require("maptools")
> require("ggplot2")
> require("plyr")

# Reading municipal boundaries

esp = readOGR(dsn=".", layer="lineas_limite_municipales_etrs89")

muni=subset(esp, esp$PROV1 == "46" | esp$PROV1 == "12" | esp$PROV1 == "3")
muni@data$id = rownames(muni@data)
muni.points = fortify(muni, region="id")
muni.df = join(muni.points, muni@data, by="id")

# Reading province boundaries

prov = readOGR(dsn=".", layer="poligonos_provincia_etrs89")

pr=subset(prov, prov$CODINE == "46" | prov$CODINE == "12" | prov$CODINE == "03" )
pr@data$id = rownames(pr@data)
pr.points = fortify(pr, region="id")
pr.df = join(pr.points, pr@data, by="id")

ggplot(muni.df) + aes(long,lat,group=group) + geom_path(color="blue") +
+ coord_equal()+ geom_path(data=pr.df, + 
aes(x=long, y=lat, group=group),color="red", size=0.5) 
这段代码绘制了一张包含所有边界的漂亮地图

对于按级别填充多边形,我尝试读取,然后按照中的建议合并

level=read.csv(“levels.dat”,header=T,sep=”“)
munlevel=合并(muni.df,level,by=“CODINE”)

但它给出了一个错误

错误en fix.by(by.x,x):“by”必须指定唯一有效的列


我不熟悉shapefile,也许我需要学习更多关于shp数据属性的知识,以找到合并这两个数据集的正确选择。如何合并数据,以便绘制线(市政边界),然后用标高填充

[NB:这个问题是一个多月前提出来的,所以OP可能找到了一种不同的方法来解决他们的问题。我在工作中偶然发现了这个问题。这个答案是为了希望它能让其他人受益。]

这似乎是OP想要的

。。。并使用以下代码生成:

require("rgdal")
require("maptools")
require("ggplot2")
require("plyr")

# read temperature data
setwd("<location if your data file>")
temp.data        <- read.csv(file = "levels.dat", header=TRUE, sep=" ", na.string="NA", dec=".", strip.white=TRUE)
temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')

# read municipality polygons
setwd("<location of your shapefile")
esp     <- readOGR(dsn=".", layer="poligonos_municipio_etrs89")
muni    <- subset(esp, esp$PROVINCIA == "46" | esp$PROVINCIA == "12" | esp$PROVINCIA == "3")
# fortify and merge: muni.df is used in ggplot
muni@data$id <- rownames(muni@data)
muni.df <- fortify(muni)
muni.df <- join(muni.df, muni@data, by="id")
muni.df <- merge(muni.df, temp.data, by.x="CODIGOINE", by.y="CODINE", all.x=T, a..ly=F)
# create the map layers
ggp <- ggplot(data=muni.df, aes(x=long, y=lat, group=group)) 
ggp <- ggp + geom_polygon(aes(fill=LEVEL))         # draw polygons
ggp <- ggp + geom_path(color="grey", linestyle=2)  # draw boundaries
ggp <- ggp + coord_equal() 
ggp <- ggp + scale_fill_gradient(low = "#ffffcc", high = "#ff4444", 
                                 space = "Lab", na.value = "grey50",
                                 guide = "colourbar")
ggp <- ggp + labs(title="Temperature Levels: Comunitat Valenciana")
# render the map
print(ggp)
连接必须在公共字段上完成,这就是大多数问题的根源。原始形状文件中的每个多边形都具有唯一的ID属性。在shapefile上运行
fortify(…)
将创建一列
id
,该列基于此。但是数据部分中没有ID列。相反,多边形ID存储为行名称。因此,首先我们必须在
muni@data
如下所示:

muni@data$id <- rownames(muni@data)
要创建贴图,我们需要根据温度级别设置填充颜色。为此,我们需要将
LEVEL
列从
temp.data
连接到
muni.df
。在
temp.data
中有一个字段
CODINE
,用于标识市政当局。现在,在
muni.df
中还有一个相应的字段
CODIGOINE
。但是有一个问题:
CODIGOINE
char(5)
,带有前导零,而
CODINE
是整数,这意味着前导零丢失(可能是从Excel导入的?)。因此,仅仅在这两个字段上进行连接不会产生匹配。我们必须首先将
CODINE
转换为带前导零的
char(5)

temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')
我们使用
merge(…)
而不是
join(…)
,因为join字段具有不同的名称,
join(…)
要求它们具有相同的名称。(注意,
join(…)
更快,如果可能的话应该使用)。因此,最后,我们有一个数据框,其中包含用于绘制多边形的所有信息和温度
级别
,可用于确定每个多边形的填充颜色

关于OP原始代码的一些注释:

  • OP的第一张地图(顶部的绿色地图)确定了“我们地区的30个不同区域……”。我找不到识别这些区域的形状文件。市政档案确定了543个市政当局,我看不出有办法将其分为30个地区。此外,温度级别文件有542行,每个市(或多或少)有一行

  • OP正在为市政当局导入线条形状文件以绘制边界。您不需要这样做,因为
    geom_polygon(…)
    将绘制(并填充)多边形,
    geom_path(…)
    将绘制边界


  • 嗨,我没找到解决办法,但我要试试你的密码。你的地图看起来令人印象深刻,正是我想要的。我不得不暂时离开这个问题,因为我以前还有其他问题要解决。非常感谢你的辛勤工作。如果这对你有帮助,请考虑选择答案(绿色复选标记)。我的SabFEFLE,你的脚本出现了一些问题。我又下载了一次,现在代码运行非常适合我的需要。干得好@jlhoward这太棒了。谢谢你的解释!我不得不做得有点不同。使用
    fortify(muni,region='id')
    (否则它不使用
    id
    变量)和
    merge
    (我想是另一个版本的
    dplyr
    )。查看此问题的更新以及地图上的一些额外功能,请访问[
    muni.df <- join(muni.df, muni@data, by="id")
    
    temp.data$CODINE <- str_pad(temp.data$CODINE, width = 5, side = 'left', pad = '0')
    
    muni.df <- merge(muni.df, temp.data, by.x="CODIGOINE", by.y="CODINE", all.x=T, a..ly=F)