2013-08-28 59 views
1

我使用ggplot2创建人口密度等值线。目前它正在为单一状态工作,但不适用于多个状态。看起来,各个县(通常有相同的名称)的密度混杂起来,有时甚至是非名称匹配县也会混淆在各州之间。例如,“新泽西州”给出了正确的密度,但“新泽西州”,“纽约州”告诉我,新泽西州人口众多的艾塞克斯郡密度为< 30p/mi^2。为什么是这样?R县的县是

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.这是非常丑陋的,但我没有访问共享文件系统现在。

以下是输出示例。正如你所看到的,纽约市人口稠密的艾塞克斯郡的代表不准确。 enter image description here

编辑:Here is my version of the CSV.对不起,因为Dropbox延迟。

+0

您的csv文件未正确读入。它似乎有一个标题标题(?!),即使删除了这些字段名称也是不正确的。 – geotheory

+0

@geotheory这很奇怪,它适合我。我删除了所有',, 2010,2011,数量,百分比,数量,百分比,人口密度,面积(平方英里),,,,线和底部的线。 –

+0

不可再生。如果我复制,粘贴并使用popdensitymap(“New Jersey”)运行''我得到'数据错误。帧(countydata $ X,countydata $ Population.Density): 参数意味着行数不同:3284,0'。首先,看起来你在'cut'的'breaks'参数中存在拼写错误,最后一个值应该是'10000'而不是'100000'?出于兴趣,如果你将它从功能中剥离出来,代码是否工作?我把一个choropleth检查和人口数据和地图多边形都很好,所以它绝对是你的代码。 – SlowLearner

回答

0

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

为了解决这个问题,合并目前由polyname完成,这意味着在countyinfopolyname无需改变和polyname添加到​​3210像这样:

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

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

+1

我会离开它。尽管说实话,我发现这是一个相当混乱的问题,但在GIS任务环境中的“合并”确实会给人们带来麻烦,而且答案可能会帮助其他人。感谢您发布您的答案。 – SlowLearner

1

只是为了证明一个简单的例子,似乎工作...

new jersey

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) 
+0

没错。单态示例可以工作。使用多个状态时会发生此问题。我会按照下面的建议尝试'sort = FALSE'。 –

+0

我觉得问题可能来自合并。 “分区域”单独与具有重复县名的多个州合并可能会使其混淆,并将相同密度分配给具有相同名称的县,因为它不知道每个分区属于哪个区域。有没有合并多个标准的方法?我想使用fips数据可以防止这种情况发生,但是如何将“fip”数字添加到'map_data'而不会遇到同样的问题? –

1

我有类似的问题制作地图,并使用merge,因为merge不一定维护秩序第一个data.frame中的行。我的解决方案是使用plyr::join代替(它往往会更快)。

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

与合并,[加入]保留x的顺序无论什么连接类型是使用 。如果需要,y的行将被添加到底部。加入是 通常比合并更快,但它的功能稍差 - 它 当前没有办法重新命名输出或合并x和y数据框中的不同 变量。

+0

''merge''sort = FALSE'有时可以修复那种[问题](http://gis.stackexchange.com/questions/37204/what-is-the-cause-of-tearing-of-polygons-赝像使用-R-ggplot - 和 - 的geom)。 – SlowLearner