R:计算两个

时间:2017-08-14 20:03:29

标签: r shapefile choropleth cartography

我试图重新创建一张地图,显示你离开克拉科夫有多少市政府: How many municipals away are you from Krakow

并将城市从克拉科夫改为弗罗茨瓦夫。地图是在GIMP完成的。

我有一个shapefile(可在此处获取:http://www.gis-support.pl/downloads/powiaty.zip)。我读了像maptoolsrgdalsf这样的shapefile文档包,但我找不到自动函数来计算它,因为我不想手动执行。

有没有这样做的功能?

致谢:地图由Hubert Szotek在https://www.facebook.com/groups/mapawka/permalink/1850973851886654/

完成

1 个答案:

答案 0 :(得分:4)

我不是那种经验丰富的网络分析,所以我必须承认不了解每一行代码,如下所示。但它的确有效!很多材料都是从这里改编而来的:https://cran.r-project.org/web/packages/spdep/vignettes/nb_igraph.html

这是最终结果:

enter image description here

代码

# Load packages
library(raster) # loads shapefile
library(igraph) # build network
library(spdep) # builds network
library(RColorBrewer)  # for plot colour palette
library(ggplot2) # plots results

# Load Data
powiaty <- shapefile("powiaty/powiaty")

首先,poly2nb函数用于计算邻近区域:

# Find neighbouring areas
nb_q <- poly2nb(powiaty)

这会创建我们的空间网格,我们可以在这里看到:

# Plot original results
coords <- coordinates(powiaty)
plot(powiaty)
plot(nb_q, coords, col="grey", add = TRUE)

enter image description here

这是我不能100%确定发生了什么。基本上,它正在计算网络中所有shapefile之间的最短距离,并返回这些对的矩阵。

# Sparse matrix
nb_B <- nb2listw(nb_q, style="B", zero.policy=TRUE)
B <- as(nb_B, "symmetricMatrix")

# Calculate shortest distance
g1 <- graph.adjacency(B, mode="undirected")
dg1 <- diameter(g1)
sp_mat <- shortest.paths(g1)

完成计算后,现在可以格式化数据以进入绘图格式,因此最短路径矩阵将与空间数据帧合并。

我不确定什么最适合用作引用数据集的ID,因此我选择了jpt_kod_je变量。

# Name used to identify data
referenceCol <- powiaty$jpt_kod_je

# Rename spatial matrix
sp_mat2 <- as.data.frame(sp_mat)
sp_mat2$id <- rownames(powiaty@data)
names(sp_mat2) <- paste0("Ref", referenceCol)

# Add distance to shapefile data
powiaty@data <- cbind(powiaty@data, sp_mat2)
powiaty@data$id <- rownames(powiaty@data)

现在数据以合适的格式显示。使用基本功能spplot,我们可以非常快速地获得图表:

displaylayer <- "Ref1261" # id for Krakow

# Plot the results as a basic spplot
spplot(powiaty, displaylayer)

我更喜欢使用ggplot来绘制更复杂的图形,因为您可以更轻松地控制样式。然而,对于如何将数据输入其中更为挑剔,因此我们需要在构建图形之前为其重新格式化数据:

# Or if you want to do it in ggplot

filtered <- data.frame(id = sp_mat2[,ncol(sp_mat2)], dist = sp_mat2[[displaylayer]]) 
ggplot_powiaty$dist == 0

ggplot_powiaty <- powiaty %>% fortify()
ggplot_powiaty <- merge(x = ggplot_powiaty, y = filtered, by = "id")
names(ggplot_powiaty)

情节。我通过删除不需要的元素并添加了背景来定制它。另外,为了使搜索中心区域变为黑色,我使用ggplot_powiaty[ggplot_powiaty$dist == 0, ]对数据进行子集化,然后将其绘制为另一个多边形。

ggplot(ggplot_powiaty, aes(x = long, y = lat, group = group, fill = dist)) +
  geom_polygon(colour = "black") +
  geom_polygon(data =ggplot_powiaty[ggplot_powiaty$dist == 0, ],
               fill = "grey60") +
    labs(title = "Distance of Counties from Krakow", caption = "Mikey Harper") +
  scale_fill_gradient2(low = "#d73027", mid = "#fee08b", high = "#1a9850", midpoint = 10) +
  theme(
    axis.line = element_blank(),
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    panel.grid.minor = element_blank(),
    panel.grid.major = element_blank(),
    plot.background = element_rect(fill = "#f5f5f2", color = NA), 
    panel.background = element_rect(fill = "#f5f5f2", color = NA), 
    legend.background = element_rect(fill = "#f5f5f2", color = NA),
    panel.border = element_blank())

enter image description here

要为帖子顶部显示的弗罗茨瓦夫绘图,只需更改displaylayer <- "Ref0264"并更新标题。