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

Tho*_*mas 5 merge r polygon ggplot2

我知道这个问题已在其他地方得到解答.我试图按照@jlhoward的指示,但显然我的技能太有限了.我可以再问你的帮助,R社区吗?

这就是我所拥有的:

瑞士的shapefile:链接

以及相应的CSV文件,用于市政名称及其邮政编码:链接

数据网站:cadastre.ch

关于最后一次流行投票的其他数据:直接链接,excel文件

我通过合并在CSV文件(wow.csv)(我要说明的数据)中添加了一列.该文件现在看起来像这样:

Gemeinden   code    Ja.Anteil   Ortschaft       PLZ Zusatzziffer    Kantonskürzel   E   N
1   Aadorf  4551    78.78638    Aawangen        8522    2           TG            710206    263564
2   Aadorf  4551    78.78638    Ettenhausen TG  8356    0           TG            710129    259411
3   Aadorf  4551    78.78638    Aadorf          8355    0           TG            710588    261648
4   Aadorf  4551    78.78638    Guntershausen   8357    0           TG            711741    258934
5   Aadorf  4551    78.78638    Wittenwil       9547    0           TG            712002    262572
Run Code Online (Sandbox Code Playgroud)

之后我试着按照@jlhoward的说明:

  1. 导入温度数据文件
  2. 导入市政的多边形shapefile
  3. muni多边形转换为数据框以进行绘图
  4. 从加入列ch12@datach12.df
  5. 从加入列wowch12.df
  6. 制作情节

我用以下代码尝试了它:

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

# read share data and the file from cadastre.ch (zip-codes)
asyl <- <- read.csv("~/FS14-1/PLZO_SHP_LV03/Asylgesetz_csv.csv", sep=";")
mydata1 <- read.table("~/FS14-1/PLZO_SHP_LV03/PLZO_CSV_LV03.csv", sep=";", quote="\"")

#merge the two files
wow <- merge(x = asyl, y = mydata1, by = "Gemeinden", all = TRUE)

# read municipality polygons
ch12 <- readOGR(work.dir, layer = "PLZO_PLZ")

# fortify and merge: muni.df is used in ggplot
ch12@data$id <- rownames(ch12@data)
ch12.df <- fortify(ch12)
ch12.df <- join(ch12.df, ch12@data, by="id")
ch12.df <- merge(ch12.df, wow, by="PLZ", all.x=T, a..ly=F)

#create the map layers
gp <- ggplot(data=ch12.df, aes(x=long, y=lat, group=group)) + 
      geom_polygon(aes(group = group))+         # draw polygons
      geom_path(color="grey", linestyle=2)+  # draw boundaries
      coord_equal() +
      scale_fill_gradient(low = "#ffffcc", high = "#ff4444", 
                             space = "Lab", na.value = "grey50",
                             guide = "colourbar")+
      labs(title="Zustimmung auf Gemeindelevel")
gp
Run Code Online (Sandbox Code Playgroud)

好吧,直到最后一步,R工作(到目前为止,我可以告诉),但如果我尝试创建ggplot,我得到没有错误,R不知何故终止.我想要实现的是根据数据控制多边形的颜色(在我的市政情况下)...

谁能帮我?

jlh*_*ard 6

你有点不清楚你要做什么,所以我需要做一些假设.

  1. 您的Excel文件具有Gemeinden(市政府)针对大规模移民的国家倡议的临时投票结果.所以我假设您想要一个等值线图,例如,%YES.接下来,我通过提取包含实际投票结果的2353行(第13行 - 2365行),添加标题(从第11行开始)并保存为,清理了Excel文件vote.csv.该列Ja in %已重命名Yes.Pct.
  2. 您的shapefile由邮政编码(PLZ)组织(或多或少).由于后面解释的各种原因,这产生了巨大的问题.所以我在Google上喋喋不休,几乎立即找到了由瑞士联邦地形办公室组织的一个shapefile .你必须以"订单"的文件,在这里,但它是免费的-所以基本上所有你需要做的是注册,他们向您发送电子邮件的链接文件.我使用的特定文件集是VEC200_Commune.*
  3. 来自地形局的文件的一个优点是它具有市政数字(大致相当于美国联邦政府使用的FIPS代码).您的Excel文件也有这些数字(Gemeinde-Nr.在Excel文件和BFSNRshapefile中调用).基于这些id的匹配比尝试匹配使用名称更可靠.

所以将所有这些放在一起产生以下地图: 从这段代码:

library(plyr)    # for join(...)
library(rgdal)   # for readOGR(...)
library(ggplot2)

setwd("< directory with all files >")
votes <- read.csv("vote.csv")
map   <- readOGR(dsn=".",layer="VEC200_Commune")
map   <- map[map$COUNTRY=="CH",]   # extract just Swiss Gemeinde

data <- data.frame(id=rownames(map@data), 
                   GEMNAME=map@data$GEMNAME,
                   BFSNR=map@data$BFSNR)
# convert id to char from factor
data$id <- as.character(data$id)
# merge vote data based on Gemeinden (different columns names in the two df...)
data    <- merge(data,votes,by.x="BFSNR",by.y="Gemeinde.Nr.", all.x=T)

map.df <- fortify(map)
map.df <- join(map.df,data,by="id")
ggplot(map.df, aes(long,lat, group=group))+
  geom_polygon(aes(fill=Yes.Pct))+
  coord_fixed()+
  scale_fill_gradient(low = "#ffffcc", high = "#ff4444", 
                      space = "Lab", na.value = "grey80",
                      guide = "colourbar")+
  labs(title="Zustimmung auf Gemeindelevel", x="", y="")+
  theme(axis.text=element_blank(),axis.ticks=element_blank())
Run Code Online (Sandbox Code Playgroud)

可以使用shapefile(基于邮政编码),但这会增加复杂性并且可能不可靠.有几个原因:

  1. 你的shapefile有4175个多边形,但只有3201个独特的邮政编码.这意味着许多PLZ都是重复的(或更糟).您的情况也是如此PLZO_CSV_LV03.csv:PLZ不是唯一的.在PLZ上合并时,这是一个问题.例如,考虑根据公共列PLZ合并两个数据帧X和Y. 如果X具有(例如具有给定PLZ的5行并且Y具有具有相同PLZ的3行),则结果将具有15行具有该PLZ.
  2. 事实证明,在合并两个 PLZ和Zusatzziffer好转,但并不能完全消除重复(即结合考虑PLC和Zusatzziffer即使,有一些重复).
  3. 没有包含PLZ的文件Gemeinde-Nr.,因此唯一的选择是合并基于的投票数据Gemeindename.这是有风险的,因为通常名称在不同来源中拼写不完全相同.
  4. PLZ shapefile非常大,部分原因是多边形的数量(4175)和部分由于空间分辨率(例如每个多边形的点数更多).结果,fortify(...)非常慢,甚至渲染地图本身也很慢.这可能就是你的R会话崩溃的原因.

考虑到所有这些警告,可以使用PLZ级shapefile生成以下映射: 使用此代码:

votes    <- read.csv("vote.csv")
zipcodes <- read.csv(sep=";","PLZO_CSV_LV03.csv")
ch12 <- readOGR(dsn=".",layer="PLZO_PLZ")
# associate id, PLZ, and Zusatzziffer
data <- data.frame(id=rownames(ch12@data), 
                   PLZ=ch12@data$PLZ, 
                   Zusatzziffer=ch12@data$ZUSZIFF)
# convert id to char from factor
data$id <- as.character(data$id)
# need to merge based on PLZ *and* Zusatzziffer
data    <- merge(data,zipcodes[2:4],by=c("PLZ","Zusatzziffer"), all.x=T)
# merge vote data based on Gemeinden (different columns names in the two df...)
data    <- merge(data,votes,by.x="Gemeindename",by.y="Gemeinden", all.x=T)

ch12.df <- fortify(ch12) 
# join data to ch12.df based in id
ch12.df <- join(ch12.df, data, by="id")

gp <- ggplot(data=ch12.df, aes(x=long, y=lat, group=group)) + 
  geom_polygon(aes(fill = Yes.Pct))+    # draw polygons
  coord_equal() +
  scale_fill_gradient(low = "#ffffcc", high = "#ff4444", 
                      space = "Lab", na.value = "grey80",
                      guide = "colourbar")+
  labs(title="Zustimmung auf Gemeindelevel", x="", y="")+
  theme(axis.text=element_blank(),axis.ticks=element_blank())
gp
Run Code Online (Sandbox Code Playgroud)

请注意,这两个地图相似,但不完全相同.我倾向于相信第一个,因为它是使用Gemeine Nr.而不是名称,因为它涉及较少的合并.