将多个SpatialPolygonDataFrames合并到R中的1个SPDF中?


22

我在QGIS中创建了2个多边形。在R中使用它们,多边形将自动变为SpatialPolygonsDataFrame(SPDF)。我想将它们合并为单个SPDF(这在ArcGis中使用Tool Merge极为简单)。我确信应该有一种简单的方法来完成R中的操作,但是我找不到方法。该合并功能似乎只合并data.frames,聚合函数溶解多个多边形为一个SHP,gIntersect(由打字加入功能)返回逻辑值,而不是在所有的SPDF。

在此处输入图片说明

数据可在此处获取:http : //ulozto.cz/xpoo5jfL/ab-zip

library(sp)
library(raster)
library(rgeos)
library(spatstat)
library(rgdal)     
library(maptools)

setwd("C:/...")
a<-readOGR(dsn=getwd(), layer="pol.a")
b<- readOGR(dsn=getwd(), layer="pol.b")

ab<-merge(a, b)  # what tool if not "merge" to use??

2
参见?rgeos :: gUnion和/或?raster :: union
mdsumner

Answers:


21

如果您不需要合并拓扑,而只需添加新的多边形,则可以简单地使用:

ab <- rbind(a,b)

如果收到“非唯一的多边形ID插槽值”错误,则表示对象的行名相同。要解决此问题,您可以使用spChFID更改行名和关联的插槽关系。由于对象中的插槽使用行名称来关联对象,因此您不能只更改@data插槽中的row.name。

b <- spChFIDs(b, paste("b", row.names(b), sep="."))

raster软件包中的union(union_sp)函数正在执行此操作,并且在后台从rgeos调用gIntersects,这是一个非常方便的辅助函数。

****编辑08-06-2018有一个未记录的参数,可用于跳过重复的ID问题。

ab <- rbind(a, b, makeUniqueIDs = TRUE) 

嗨,谢谢,我尝试了此操作,但遇到了一个错误:validObject(res)中的错误:无效的类“ SpatialPolygons”对象:非唯一的Polygons ID插槽值。我该如何处理该错误?
maycca 2015年

3
您可以这样做: ab <- bind(a, b) 避免发生该错误
罗伯特·希曼斯

raster :: union当前不适用于spatialPOINTSdataframes
Mox

19

@mdsumner提供的超级简单的解决方案:

library(sp)
library(raster)
library(rgeos)
library(spatstat)
library(rgdal)     
library(maptools)

setwd("C:/...")
a<-readOGR(dsn=getwd(), layer="pol.a")
b<- readOGR(dsn=getwd(), layer="pol.b")

# use union in {raster} package ?raster::union
ab<-union(a, b)

导致:

类(ab)

[1] "SpatialPolygonsDataFrame"
attr(,"package")
[1] "sp"

在此处输入图片说明


6
由光栅的作者Robert Hijmans提供的超级简单解决方案:)
mdsumner

“联盟”(当前)不适用于spatialpoints数据帧,尽管在下一发行版中我被告知会这样做。@RobertH建议使用rbind,尽管我不清楚它是如何工作的。
Mox


看起来也raster::union适用于SpatialLinesDataFrame类!
philiporlando

1
library(sp)
data(meuse)
plot(meuse)
slotNames(meuse) #".Data"     "names"     "row.names" ".S3Class" 
coordinates(meuse) <- ~x+y #Add "ID" column to "meuse"
slotNames(meuse) #[1] "data"        "coords.nrs"  "coords"      "bbox"        "proj4string"
class(meuse) #[1] "SpatialPointsDataFrame"
names(meuse@data)
#[1] "cadmium" "copper"  "lead"    "zinc"    "elev"    "dist"    "om"      "ffreq"   "soil"    "lime"   
#[11] "landuse" "dist.m"
meuse@data <- data.frame(ID=1:nrow(meuse), meuse@data) #adds an ID field
names(meuse@data)
#[1] "ID"      "cadmium" "copper"  "lead"    "zinc"    "elev"    "dist"    "om"      "ffreq"   "soil"   
#[11] "lime"    "landuse" "dist.m" 
#Create a data.frame "df.new" with "IDS" (note different name) and "y" columns.
meuse_table.df <- data.frame(IDS=1:nrow(meuse), y=runif(nrow(meuse)))
class(meuse_table.df) #"data.frame"
#Now we can merge "df.new" to "meuse" (@data slot)
meuse <- merge(meuse, meuse_table.df, by.x = "ID", by.y = "IDS")
#create a new file named meuse, consisting of a merge of:
#   the meuse spatial points (from the original)
#   the dataframe created from the original, using the data.frame command
#   BY the field "ID" in the spatialpointsdataframe
#   By the field "IDS" in the tabular dataframe (df.new) 
head(meuse@data)
# I think the source of unease is that adding an ID field to both files 
#is based on them having the same number of rows in the same order. 
#in ArcGIS, this would be an unreasonable and dangerous assumption.
#R seems to have some sort of 'innate' key field, based on the order read it. 
#This is all great when splitting one file, and merging it back together.
#but what about two files? 
#I think it can be done, but it's a three-step process. 
#First, merge the polygons. Add an ID field, as above.
#Second, merge the tables (as dataframes), and add ID's. as above. 
#Third, attach the merged tables to the merged polygons. 
#For it to work, the order of things in the merge (polgyons, dataframe) needs be identfical. 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.