如何使用ggmap正确连接数据和几何

时间:2017-09-18 10:55:11

标签: r ggmap

一张图片胜过千言万语: Data does not match geometry

观察到的行为:从上图中可以看出,国家/地区的名称与其实际几何图形不匹配。

预期行为:我想将数据框与其几何图形正确连接,并在ggmap中显示结果。

我以前加入过不同的数据框,但事实上显然ggmap需要“强化”(实际上我不知道究竟是什么意思)数据框才能显示结果。

这是我到目前为止所做的:

library(rgdal)
library(dplyr)
library(broom)
library(ggmap)

# Load GeoJSON file with countries.
countries = readOGR(dsn = "https://gist.githubusercontent.com/ccamara/fc26d8bb7e777488b446fbaad1e6ea63/raw/a6f69b6c3b4a75b02858e966b9d36c85982cbd32/countries.geojson")

# Load dataframe.
df = read.csv("https://gist.githubusercontent.com/ccamara/fc26d8bb7e777488b446fbaad1e6ea63/raw/a6f69b6c3b4a75b02858e966b9d36c85982cbd32/sample-dataframe.csv")

# Join geometry with dataframe.
countries$iso_a2 = as.factor(countries$iso_a2)
countries@data = left_join(countries@data, df, by = c('iso_a2' = 'country_code'))

# Convert to dataframe so it can be used by ggmap.
countries.t = tidy(countries)

# Here's where the problem starts, as by doing so, data has been lost!

# Recover attributes' table that was destroyed after using broom::tidy.
countries@data$id = rownames(countries@data) # Adding a new id variable.
countries.t = left_join(countries.t, countries@data, by = "id")

ggplot(data = countries.t,
       aes(long, lat, fill = country_name, group = group)) +
  geom_polygon() +
  geom_path(colour="black", lwd=0.05) + # polygon borders
  coord_equal() +
  ggtitle("Data and geometry have been messed!") +
  theme(axis.text = element_blank(), # change the theme options
        axis.title = element_blank(), # remove axis titles
        axis.ticks = element_blank()) # remove axis ticks

2 个答案:

答案 0 :(得分:2)

虽然你的工作是一种合理的方法 - 我想重新考虑你的设计,主要是因为两个简单的原因:

1)虽然GeoJSON是未来,但R仍然在很大程度上依赖于sp包及其对应的sp *对象 - 很快你希望你早日切换。它只是关于包,而且大多数(如果不是全部)都依赖于sp *对象。

2)ggplot与ggmap相结合具有很好的绘图功能 - 但与sp *结合使用R +的传单相比,它仍然非常有限。

可能最快捷的方式很简单:

library(sp)
library(dplyr)
library(geojsonio)
library(dplyr)
library(tmap)

#get sp* object instead of geojson
countries <- geojsonio::geojson_read("foo.geojson",what = "sp")

#match sp* object with your data.frame
countries@data <- dplyr::left_join(countries@data, your_df, by = 
c("identifier_1" = "identifier_2"))

#creates a fast and nice looking plot / lots of configuration available
p1 <- tm_shape(countries) +
      tm_polygons() 
p1

#optional interactive leaflet plot
tmap_leaflet(p1)

如果有小问题,这是我脑袋里写的。

这是一种不同的方法,但至少在我看来,现在R中的方法更快更简洁(希望geojson将来会获得更多的支持)。

答案 1 :(得分:1)

有混乱行为的原因。

countries最初是一个包含 177 元素的大型SpatialPolygonsDataFrame(相当于countries@data中的177行)。当您在left_joincountries@data上执行df时,countries中的元素数量不会受到影响,但countries@data中的行数会增加到<强> 210

使用countries强化broom::tidycountries及其177个元素转换为id从0到176的数据框。(我不知道为什么它是零索引的,但我通常更喜欢明确指定区域)。

另一方面,基于idcountries@data添加到rownames(countries@data)会导致id值从1运行到210,因为这是{中的行数} {1}}之前加入countries@data后的{1}}。因此,一切都不同步。

请尝试以下方法:

df

enter image description here

P.S。你实际上并不需要ggmap包。只是它加载的ggplot2包。