将.csv中的属性加入.dbf文件后加载.shp文件时出错

时间:2013-11-08 21:17:10

标签: r csv

在将csv文件中的属性加入dbf文件后,我在R中打开.shp文件时遇到问题。我在R中有很多编码经验,但在R中使用GIS的经验有限。我有ArcGIS的经验,但不再能访问该程序。我知道如何使用csv文件和绘图点在R中创建气泡图和其他地图,但我希望能够将属性添加到.dbf,然后使用shapefile使用brewer调色板填充县区域。在将属性加入.dbf文件之前,我可以打开形状文件(文件来自美国人口普查局网页)。

以下是我的代码:

library(gpclib)
library(maptools)
library(RColorBrewer)
library(classInt)
library(TeachingDemos)


gci<-read.csv("C:/Users/Smackbug/marketingmapexample.csv", header=TRUE) #Has Geo_ID
#read in dbf file to append data
gci2<-gci
gci2<-na.omit(gci2) #remove any empty data points

#read in dbf file to add attributes
akdbf<-read.dbf(file.choose())#downloaded from the us census bureau

#merge to join attributes
joined<-merge(akdbf,gci2, by=c("GEO_ID"))
#Save original and new dbf
write.dbf(akdbf, "C:/Users/Smackbug/Desktop/shapefiles/gz_2010_02_060_00_500koriginal.dbf")
write.dbf(joined, "C:/Users/Smackbug/Desktop/shapefiles/gz_2010_02_060_00_500k.dbf")

我从代码的这一部分得到了错误

**alaska<-readShapePoly(file.choose(),proj4string=CRS("+proj=longlat") )
Error in `row.names<-.data.frame`(`*tmp*`, value = value) : 
  invalid 'row.names' length**

以及代码的其余部分

#the rest of the code should look something like this

colors<-brewer.pal(5,"Reds")
brks<-classIntervals(alaska$medianIncome, n=5, style="fixed", fixedBreaks=c(0,25,50,100,250))
plot(brks, pal=colors)
brks<-brks$brks
plot(alaska, col=colors[findInterval(alaska$medianIncome, brks, all.inside=TRUE)], axes=F)

2 个答案:

答案 0 :(得分:0)

您正在以多种方式破坏sp(shapefile)对象。您不能独立于shapefile上的操作将数据添加到dbf。所有内容都在包含shapefile的二进制文件(shx)中编入索引。您还通过使用合并来破坏sp对象的内部关系。

最有效的方法是使用rgdal读取shapefile,加入dbf,最后写出(或覆盖)一个新的shapefile。

require(rgdal)
require(sp)
require(foreign)

# Read data
shp <- readORG(getwd(), "ShpName")
tbl <- read.dbf("infile.dbf")

# Merge data using match
shp@data = data.frame(shp@data, tbl[match(shp@data[,"GEO_ID"], tbl[,"GEO_ID"]),])

# Write new shapefile with added attributes, THe additional flags will overwrite if 
#   the name is the same as the original 
writeOGR(shp, getwd(), "NewShp", driver="ESRI Shapefile", check_exists=TRUE, overwrite_layer=TRUE)

如果您需要更正式的合并功能,可以使用它。

##########################################################################
# PROGRAM: merge.sp.df
#
# USE: JOINS A dataframe OBJECT TO A sp CLASS SpatialDataFrame OBJECT
#        KEEPING INTEGRITY OF DATA
# 
# REQUIRES: sp CLASS SpatialDataFrame OBJECT 
#    PACKAGES: sp
#
# ARGUMENTS: 
#   x       sp SpatialDataFrame OBJECT
#   y       dataframe OBJECT TO MERGE
#   xcol    MERGE COLUMN NAME IN sp OBJECT
#   ycol    MERGE COLUMN NAME IN dataframe OBJECT
#
# EXAMPLE:
#   # Not Run (dat.sp is sp object and dat is a data.frame to merge
#   dat.sp <- merge.sp.df(dat.sp, dat, "dat.sp-ID", "dat-ID")
#
# VALUE:
#   A NEW SpatialDataFrame OBJECT WITH MERGED DATA
##########################################################################
merge.sp.df <- function(x, y, xcol, ycol) {
  x@data$sort <- 1:nrow(as(x@data, "data.frame"))  
    xdf <- as( x@data, "data.frame")
     xdf <- merge(xdf, y, by.x=xcol, by.y=ycol) 
       xdf <- xdf[order(xdf$sort), ]
         row.names(xdf) <- xdf$sort
      xdf <- xdf[,- which(names(xdf) == "sort")]     
    x@data <- xdf  
   return(x)
}

答案 1 :(得分:0)

以上是Jeffery的代码中的一些工作结果(感谢Jeffery的帮助):

library(sp)
library(rgdal)
library(foreign)

setwd("C:/Users/rhonda/Documents/R scripts/shapefiles")
gc<-read.csv("gcmarketingmapexample.csv", header=TRUE) 
#read in dbf file to append data
akdbf<-read.dbf("gz_2010_02_060_00_500k.dbf")
#merge to join attributes
joined<-merge(akdbf,gc, by=c("GEO_ID")`enter code here`

#save new dbf 
write.dbf(joined, "akdbf")

#Shape File and DBF file 
frame<-readOGR(getwd(),"gz_2010_02_060_00_500k")
akdbf2<-read.dbf("akdbf.dbf")

frame@data=akdbf2[match(frame@data[,"GEO_ID"], akdbf2[,"GEO_ID"]),]
writeOGR(frame,getwd() , "akdbf",driver="ESRI Shapefile", check_exists=TRUE, overwrite_layer=TRUE)
#use new shapefiles to create maps