我正在尝试在这个问题中提出同样的问题Cartogram + choropleth map in R,但是从SpatialPolygonsDataFrame开始并希望最终得到相同类型的对象。
我可以将对象保存为shapefile,使用scapetoad,重新打开它并转换回来,但我宁愿把它全部放在R中,这样程序就可以完全重现了,所以我可以编写几十个变化自动。
我已经在github上分享了Rcartogram代码,并加入了我迄今为止的努力here。
本演示基本上是在地图上创建一个SpatialGrid,在网格的每个点查找人口密度,并将其转换为cartogram()
所需格式的密度矩阵。到目前为止一切都很好。
但是,如何根据cartogram()
的输出插入原始地图点?
这里有两个问题。第一种是将地图和网格放入相同的单位以允许插值。第二种是访问每个多边形的每个点,对其进行插值,并使它们保持正确的顺序。
网格采用网格单位,地图采用投影单位(例如longlat示例)。必须将网格投影到longlat中,或将地图投影到网格单元中。我的想法是制作一个假的CRS,并将其与spTransform()
中的package(rgdal)
函数一起使用,因为它可以轻松处理对象中的每个点。
访问每个点很困难,因为它们是SpPDF对象的几个层:对象>多边形>多边形>线> coords我认为。任何想法如何访问这些,同时保持整个地图的结构完整?
答案 0 :(得分:2)
这个问题可以通过Chris Brunsdon's GitHub上提供的getcartr
软件包解决,在this博文中有详细说明。
quick.carto
函数完全符合您的要求 - 以SpatialPolygonsDataFrame
作为输入并输出SpatialPolygonsDataFrame
。
在博客文章中重现示例的精髓,以防链接失效,我自己的风格混合在&拼写错误:
(Shapefile; World Bank population data)
library(getcartr)
library(maptools)
library(data.table)
world <- readShapePoly("TM_WORLD_BORDERS-0.3.shp")
#I use data.table, see blog post if you want a base approach;
# data.table wonks may be struck by the following step as seeming odd;
# see here: http://stackoverflow.com/questions/32380338
# and here: https://github.com/Rdatatable/data.table/issues/1310
# for some background on what's going on.
world@data <- setDT(world@data)
world.pop <- fread("sp.pop.totl_Indicator_en_csv_v2.csv",
select = c("Country Code", "2013"),
col.names = c("ISO3", "pop"))
world@data[world.pop, Population := as.numeric(i.pop), on = "ISO3"]
#calling quick.carto has internal calls to the
# necessary functions from Rcartogram
world.carto <- quick.carto(world, world$Population, blur = 0)
#plotting with a color scale
x <- world@data[!is.na(Population), log10(Population)]
ramp <- colorRampPalette(c("navy", "deepskyblue"))(21L)
xseq <- seq(from = min(x), to = max(x), length.out = 21L)
#annoying to deal with NAs...
cols <- ramp[sapply(x, function(y)
if (length(z <- which.min(abs(xseq - y)))) z else NA)]
plot(world.carto, col = cols,
main = paste0("Cartogram of the World's",
" Population by Country (2013)"))