【问题标题】:Counties are scrambled in R县在 R 中被打乱
【发布时间】:2013-08-28 16:24:57
【问题描述】:

我正在使用ggplot2 创建人口密度等值线。它目前适用于单个州,但不适用于多个州。似乎各个县(通常具有相同名称)的密度混淆了,有时甚至不匹配的县也会在州之间混淆。例如,“New Jersey”给出了正确的密度,但“New Jersey”、“New York”告诉我新泽西州人口众多的埃塞克斯县的密度

library(stringr)
library(ggplot2)
library(scales)
library(maps)

popdensitymap <- function(...){
path <- "U:/maps-county2011.csv"

states <- list(...)
countydata <- read.csv(path, sep=",")

countydata <- data.frame(countydata$X, countydata$Population.Density)
names(countydata) <- c("fips", "density")

data(county.fips)

cdata <- countydata
cdata$fips <- gsub("^0", "", cdata$fips)
countyinfo <- merge(cdata, county.fips, by.x="fips", by.y="fips")

countyinfo <- data.frame(countyinfo, str_split_fixed(countyinfo$polyname, ",", 2))
names(countyinfo) <- c('fips', 'density', 'polyname', 'state', 'county')
countyshapes <- map_data("county", states)
countyshapes <- merge(countyshapes, countyinfo, by.x="subregion", by.y="county")
choropleth <- countyshapes
choropleth <- choropleth[order(choropleth$order), ]
choropleth$density_d <- cut(choropleth$density, breaks=c(0,30,100,300,500,1000,3000,5000,100000))

state_df <- map_data("state", states)
density_d <- choropleth$density_d  
choropleth <- choropleth[choropleth$state %in% tolower(states),]


p <- ggplot(choropleth, aes(long, lat, group=group))
p <- p + geom_polygon(aes(fill=density_d), colour=alpha("white", 1/2), size=0.2)
p <- p + geom_polygon(data = state_df, colour="black", fill = NA)
p <- p + scale_fill_brewer(palette="PuRd")
p
}

使用,

popdensitymap("New Jersey")
popdensitymap("New York", "New Jersey")

Here is the csv. 很丑,但是我现在没有文件共享系统。

这是一个输出示例。如您所见,纽约市人口众多的埃塞克斯县的代表不准确。

编辑:Here is my version of the CSV. 抱歉,保管箱延迟。

【问题讨论】:

  • 您的 csv 文件没有正确读入。它似乎有一个标题标题 (?!),即使将其删除,字段名称也不正确。
  • @geotheory 这很奇怪,它对我来说很好用。我删除了直到,,,2010,2011,Number,Percent,Number,Percent,Population Density,Area (Square Miles),,,, 行和底部行的所有内容。
  • 不可重现。如果我使用popdensitymap("New Jersey") 复制、粘贴和运行,我会得到Error in data.frame(countydata$X, countydata$Population.Density) : arguments imply differing number of rows: 3284, 0。一方面,看起来你的breaks 参数中有一个错字cut,最后一个值应该是10000 而不是100000?出于兴趣,如果将代码从函数中剥离出来,代码是否有效?我整理了一个等值线来检查,人口数据和地图多边形都很好,所以这绝对是你的代码。
  • @SlowLearner 我添加了 CSV 的裁剪版本。它仍然可以重现吗?

标签: r csv ggplot2 heatmap


【解决方案1】:

只是为了证明一个更简单的例子似乎有效......

library(ggplot2)
library(scales)
library(maps)

csv.file <- "http://www.census.gov/popest/data/maps/2011/maps-county2011.csv"

mydf <- read.csv(csv.file, skip = 4, header = TRUE, check.names = FALSE)
mydf <- mydf[, c(1, 2, 5, 10, 11)] # we can drop most columns

colnames(mydf) <- c("code", "subregion", "population", "density", "area")
mydf$population <- as.numeric(gsub(",", "", mydf$population)) # remove commas
mydf$area <- as.numeric(gsub(",", "", mydf$area)) # remove commas

nj.pop <- mydf[substr(mydf$code, 1, 3) == '340', ] # new jersey code is 34000
nj.pop <- nj.pop[2:nrow(nj.pop), ] # drop first row i.e. new jersey state itself
nj.pop$subregion <- tolower(gsub(" County", "", nj.pop$subregion))
nj.pop$subregion <- gsub("\\.", "", nj.pop$subregion)
nj.pop$density_d <- cut(nj.pop$density,
                        breaks = c(0,30,100,300,500,1000,3000,5000,100000),
                        dig.lab = 6, include.lowest = TRUE)

nj.pop

nj.shp <- map_data("county") # grab...
nj.shp <- nj.shp[nj.shp$region == 'new jersey', ] # ...and subset

identical(unique(nj.shp2$subregion), unique(nj.pop$subregion)) # should be TRUE

nj.both <- merge(nj.pop, nj.shp2, by = "subregion")

p <- ggplot(nj.both, aes(long, lat, group = group)) +
    geom_polygon(aes(fill = density_d), colour = alpha("white", 1/2),
                 size = 0.2) +
    scale_fill_brewer(palette = "PuRd") +
    coord_equal()

print(p)

【讨论】:

  • 没错。单态示例确实有效。使用多个状态时会出现此问题。我会按照您在下面的建议尝试sort=FALSE
  • 我觉得问题可能出在合并上。单独由subregion 与具有重复县名的多个州合并可能会混淆它并将相同的密度分配给具有相同名称的县,因为它不知道每个子区域属于哪个区域。有没有办法与多个标准合并?我想使用 fips 数据可以防止这种情况发生,但是如何将 fips 编号添加到 map_data 而不会遇到同样的问题?
【解决方案2】:

我在制作地图和使用merge 时遇到过类似的问题,因为merge 不一定保留第一个data.frame 中的行顺序。我的解决方案是改用plyr::join(这也往往更快)。

一个缺点是您加入的列需要在两个数据框中具有相同的名称。来自?join

与合并不同,[join] 保留 x 的顺序,无论连接类型是什么 用过的。如果需要,来自 y 的行将被添加到底部。加入是 通常比合并更快,尽管它的功能有点少 - 它 目前无法重命名输出或合并不同的 x 和 y 数据框中的变量。

【讨论】:

  • mergesort = FALSE 有时可以修复那种problem
【解决方案3】:

好吧,我真的明白了。 SlowLearner 和 shujaa 让我意识到问题在于,不同州的同名县没有分配到正确的人口密度。

为了解决这个问题,合并现在由 polyname 完成,这意味着无需更改 countyinfo 中的 polyname 并将 polyname 添加到 countyshapes,如下所示:

countyshapes$polyname <- paste(countyshapes$region, countyshapes$subregion, sep=",")

感谢您的帮助。我不确定是否应该删除该问题或将其留作参考。

【讨论】:

  • 我会离开它。虽然老实说,我发现这是一个相当混乱的问题,但merge 在 GIS 任务的上下文中确实会给人们带来问题,而答案可能会对其他人有所帮助。感谢您发布您的答案。
猜你喜欢
  • 2015-11-14
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2018-08-27
  • 1970-01-01
相关资源
最近更新 更多