绘制英国公投地图

浏览: 1528

Clipboard Image.png

以下将会学习到:

  1. geojson地图格式数据

  2. 英国公投网页数据抓取

  3. stringdist包中的模糊匹配

  4. 脱欧地图可视化的建立

概述

    最近最火的国际事件莫过于英国的“退欧”公投了,6月24日英国公投全部计票结束,51.9%的选民支持英国脱离欧盟。周围小伙伴们都议论纷纷,而之后的连锁反应也让人应接不暇,英国首相卡梅伦宣布将辞去首相职务,英国逾50万人请愿二次公投,还有民众发起请愿,呼吁伦敦独立加入欧盟。恍惚间,经过一觉醒来,英国人民又后悔自己的“选择”。那让我们通过数据地图方式,来看看脱欧公投,英国各地的投票情况。(全文代码来自robin的github)

创建选举结果区域地图

1. 获取权威地图信息

首先让我们获取应该的地图信息,这里通过github,获取Geojson格式的英国地图信息。GeoJSON是一种地理数据结构的描述格式,其结构同JSON,我们可以简单理解为加带一定条件的json格式数据,通过geojson_read()读取到las。
pkgs = c("rvest", "geojsonio", "tmap", "dplyr","stringdist")
lapply(pkgs, library, character.only = T)
url = "https://github.com/npct/pct-bigdata/raw/master/las-dbands.geojson"
download.file(url, "las.geojson")
las = geojson_read("las.geojson", what = "sp")

2. 网络抓取选举结果

通过bbc的EU Referendum <http://www.bbc.co.uk/news/politics/eu_referendum/results/local/a>,可以看到英国不同州郡的脱欧公投比例,通过XML格式数据的抓取方法,我们可以抓取到以字母A开头的各郡县名称及选择愿意“脱欧”的比例,并运用tmap包qtm()函数快速作图,该图是字母A开头的郡县公投数据展示。
url = "http://www.bbc.co.uk/news/politics/eu_referendum/results/local/a"
bbc = read_html(url)
#抓取A开头的郡县名称
la_name = bbc %>%
 html_nodes(".eu-ref-result-bar__title") %>%
 html_text()
#抓取公投比例数据
vote_leave = bbc %>%
 html_nodes(".eu-ref-result-bar__party-votes--percentage") %>%
 html_text() %>%
 gsub(pattern = " |%", replacement = "") %>%
 as.numeric()
#仅保留愿意“脱欧”的比例
vote_leave = vote_leave[(1:length(la_name)) * 2 - 1]
ref_result = data_frame(geo_label = la_name, `% vote leave` = vote_leave)
#把获取的公投数据与geojson地图数据拼接
las@data = left_join(las@data, ref_result)
#运用tmap包qtm()函数快速作图
qtm(las, "% vote leave")


3. 抓取全部郡县公投数据

    以上只是抓取的以字母A开头的郡县公投数据,接下来我们根据字母顺序,运用同样方法依次抓取其他全部郡县公投数据。
i = "b"for(i in letters[-1]){
 url = "http://www.bbc.co.uk/news/politics/eu_referendum/results/local/"
 url = paste0(url, i)
 url_exists = RCurl::url.exists(url)
 if(!url_exists) next
 bbc = read_html(url)
 la_name = bbc %>%
   html_nodes(".eu-ref-result-bar__title") %>%
   html_text()
 vote_leave = bbc %>%
   html_nodes(".eu-ref-result-bar__party-votes--percentage") %>%
   html_text() %>%
   gsub(pattern = " |%", replacement = "") %>%
   as.numeric()
   vote_leave = vote_leave[(1:length(la_name)) * 2 - 1]
 ref_res_tmp = data_frame(geo_label = la_name, `% vote leave` = vote_leave)
 ref_result = bind_rows(ref_result, ref_res_tmp)}
ref_result_orig = ref_resultlas = geojson_read("las.geojson", what = "sp")
las$geo_label = as.character(las$geo_label)

4. 对郡县名称进行模糊匹配

    抓取完所有郡县公投数据后,会出现抓取地名与Geojson地图中geo_label列表数据不完全一致情况,因此,需要采用手动匹配或自动模糊匹配方式,进行字段匹配。
手动匹配很好理解,通过发现抓取ref_result列表地名与las$geo_label列表不一致时,进行替换,我们看到有40个地名出现不一致;自动匹配则用到stringdist包中的模糊匹配amatch()函数,方法选用“osa”(Optimal String Alignment distance)方法,当然也可以选择“lv”、“soundex”等方法,可以help查看学习。字符串最大距离设置为3。
# 手动匹配
ref_result$geo_label[grep("Corn", ref_result$geo_label)] =
 las$geo_label[grep("Corn", las$geo_label)]
ref_result$geo_label[grep("Heref", ref_result$geo_label)] =
 las$geo_label[grep("Heref", las$geo_label)]
# 自动匹配
msel = !ref_result$geo_label %in% las$geo_label
mismatches
= ref_result$geo_label[msel]
ams = amatch(mismatches, las$geo_label, method = "osa", maxDist =3)
pmatches = cbind(as.character(las$geo_label[ams]),ref_result$geo_label[msel])
las@data = left_join(las@data, ref_result)

5. 绘制脱欧公投地图

    运用tmap包快速绘制脱欧地图,我们把公投比例-50,以不同颜色标明不同地区对待公投的态度。
las$`% vote leave` = las$`% vote leave` - 50
tm <- tm_shape(las) +
 tm_fill("% vote leave", palette = "RdBu",    title = "% vote leave\n(swing)") +
 tm_borders(lwd = 0.1)print(tm)


说明

本文来自于Robin的github<https://github.com/Robinlovelace>,是对其代码的翻译和学习,不涉及任何版权和政治商业利益。

参考资料

  • scan help文档等

推荐 1
本文由 余文华 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册