我正在使用ggplot2
来创建人口密度等值线。它目前适用于单个状态,但不适用于倍数。似乎各个县(通常具有相同名称)的密度混淆,有时甚至非名称匹配县在各州之间混淆。例如,“New Jersey”给出了正确的密度,但“New Jersey”,“New York”告诉我,新泽西州人口众多的Essex县的密度<30p / mi ^ 2。为什么是这样?
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.这非常难看,但我现在无法访问文件共享系统。
以下是输出示例。正如您所看到的,纽约市人口众多的埃塞克斯郡(Essex County)的代表性不准确。
编辑:Here is my version of the CSV.抱歉投递箱延迟。
答案 0 :(得分: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)
答案 1 :(得分:1)
我在制作地图和使用merge
方面遇到了类似的问题,因为merge
不一定保留第一个data.frame中的行顺序。我的解决方案是使用plyr::join
代替(也往往更快)。
一个缺点是您加入的列需要在两个数据框中具有相同的名称。来自?join
:
与merge不同,[join]保留x的顺序,无论连接类型是什么 用过的。如果需要,y中的行将添加到底部。加入是 通常比合并更快,虽然它的功能稍差 - 它 目前无法在不同的位置重命名输出或合并 x和y数据框中的变量。
答案 2 :(得分:0)
好的,我真的明白了。 SlowLearner和shujaa让我意识到问题在于,不同州的同名县没有被分配正确的人口密度。
为了解决这个问题,合并现在由polyname
完成,这意味着polyname
中countyinfo
无需更改,polyname
添加到countyshapes
像这样:
countyshapes$polyname <- paste(countyshapes$region, countyshapes$subregion, sep=",")
感谢您的帮助。我不确定是否应删除该问题或将其留待参考。