我知道elsewhere已经回答了这个问题。我试图按照@jlhoward的指示进行操作,但显然我的技能太有限了。我可以再问一问您的帮助吗,R社区?

这是我所拥有的:

瑞士的shapefile:Link

以及相应的CSV文件,其中包含市镇名称及其邮政编码:Link

数据网站:cadastre.ch

上次热门投票的其他数据:Direct link, excel-file

我通过合并将一列添加到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

之后,我尝试遵循@jlhoward的指示:
  • 导入温度数据文件
  • 导入市的多边形shapefile
  • muni多边形转换为数据框以绘制
  • 连接从ch12@datach12.df的列
  • 连接从wowch12.df的列
  • 绘制情节

  • 我用以下代码尝试了它:
    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
    

    好吧,直到最后一步,R都起作用了(到目前为止,我可以说出),但是如果我尝试创建ggplot,我不会收到任何错误,并且R会以某种方式终止。我想要实现的是根据数据控制多边形的颜色(在我的市属情况下)...

    谁能帮我?

    最佳答案

    目前尚不清楚您要做什么,因此我需要做一些假设。

  • 您的Excel文件具有Gemeinden(市政府)反对大规模移民的国家倡议的临时投票结果。因此,我假设您想要一个显示例如%YES的choropleth贴图。接下来,我通过提取包含实际投票结果的2353行(行13-2365),添加标题(来自第11行)并将其另存为vote.csv,稍微清理了Excel文件。列Ja in %被重命名为Yes.Pct
  • 您的shapefile是由邮政编码(PLZ)来组织的(或多或少)。由于稍后解释的各种原因,这产生了巨大的问题。因此,我在Google上进行了一些摸索,几乎立即在Swiss Federal Office of Topography上找到了由市政当局组织的shapefile。您必须“订购”文件here,但它是免费的-因此,您基本上要做的就是注册,然后他们会通过电子邮件将文件的链接发送给您。我使用的特定文件集是VEC200_Commune.*
  • 地形办公室提供的文件的一个优点是它具有市政号码(大致等同于美国联邦政府使用的FIPS代码)。您的Excel文件还具有这些数字(在Excel文件中称为Gemeinde-Nr.,在shapefile中称为BFSNR)。与尝试使用名称进行匹配相比,基于这些ID进行匹配要可靠得多。

  • 因此,将所有这些放在一起将产生以下 map :

    从此代码:
    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())
    

    可以使用shapefile(基于邮政编码),但这会增加复杂性并且可能不可靠。有以下几个原因:
  • 您的shapefile具有4175个多边形,但只有3201个唯一的邮政编码。这意味着许多PLZ是重复的(或更糟的是)。 PLZO_CSV_LV03.csv也是如此:PLZ不是唯一的。当您在PLZ上合并时,这是一个问题。考虑一个示例,您基于一个公共(public)列PLZ合并两个数据框X和Y。如果X具有给定PLZ的5行,而Y具有相同PLZ的3行,则该PLZ具有15行。
  • 事实证明,合并PLZ和Zusatzziffer可以改善这种情况,但是并不能完全消除重复(也就是说,即使将PLC和Zusatzziffer结合使用,也会存在一些重复)。
  • 包含文件的PLZ都没有Gemeinde-Nr.,因此唯一的选择是合并基于Gemeindename的投票数据。这是有风险的,因为名称经常在不同的来源中拼写不完全相同。
  • PLZ shapefile非常大,部分原因是多边形的数量(4175),部分原因是空间分辨率(例如,每个多边形有更多点)。结果,fortify(...)非常慢,甚至渲染 map 本身也很慢。这可能就是您的R session 崩溃的原因。

  • 考虑到所有这些注意事项,可以使用PLZ级别的shapefile生成以下 map :

    使用此代码:
    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
    

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

    10-08 08:12