Mehrere SpatialPolygonDataFrames in 1 SPDF in R zusammenführen?

22

Ich habe 2 Polygone in QGIS erstellt. Wenn Sie sie in R verwenden, werden Polygone automatisch zu SpatialPolygonsDataFrame (SPDF). Ich möchte sie in einzelne SPDF zusammenführen (wie es in ArcGis mit Tool Merge sehr einfach ist ). Ich bin mir sicher, dass es eine einfache Möglichkeit geben sollte, dies in R zu vervollständigen, aber ich kann nicht herausfinden, wie. Die Merge- Funktion scheint nur data.frames zusammenzuführen. Die Aggregatfunktion löst mehrere Polygone in einem SHP auf. gIntersect (durch Eingabe der Join-Funktion) gibt einen logischen Wert zurück, nicht jedoch das SPDF.

Bildbeschreibung hier eingeben

Daten sind hier verfügbar: 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??
Maycca
quelle
2
Siehe? Rgeos :: gUnion und / oder? Raster :: union
mdsumner

Antworten:

21

Wenn Sie keine Topologie zusammenführen müssen, sondern nur neue Polygone hinzufügen möchten, können Sie einfach Folgendes verwenden:

ab <- rbind(a,b)

Wenn der Fehler "Nicht eindeutige Werte für Polygon-ID-Slots" angezeigt wird, bedeutet dies, dass die Rownamen der Objekte identisch sind. Um dies zu beheben, können Sie spChFIDs verwenden, um die Rownamen und die zugehörigen Slot-Beziehungen zu ändern. Da die Slots im Objekt die Rownamen verwenden, um das Objekt zuzuordnen, können Sie nicht einfach row.names im Slot @data ändern.

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

Die union (union_sp) -Funktion im Raster-Paket erledigt dies und ruft gIntersects von rgeos hinter den Kulissen auf. Dies ist eine sehr praktische Hilfsfunktion.

**** Edit 08-06-2018 Es gibt ein undokumentiertes Argument, mit dem das Problem der doppelten ID übersprungen werden kann.

ab <- rbind(a, b, makeUniqueIDs = TRUE) 
Jeffrey Evans
quelle
Hallo, danke, ich habe es versucht, habe aber einen Fehler erhalten: Fehler in validObject (res): Ungültiges Objekt der Klasse "SpatialPolygons": Nicht eindeutige Werte für den ID-Slot von Polygons. Wie kann ich mit diesem Fehler umgehen?
Maycca
3
Sie können tun: ab <- bind(a, b) um diesen Fehler zu vermeiden
Robert Hijmans
raster :: union funktioniert derzeit nicht mit spatialPOINTSdataframes
Mox
19

Super einfache Lösung von @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)

führte zu :

Klasse (ab)

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

Bildbeschreibung hier eingeben

Maycca
quelle
6
Super einfache Lösung zur Verfügung gestellt von Robert Hijmans, der Autor von Raster :)
mdsumner
'Union' funktioniert (derzeit) nicht für Datenrahmen mit räumlichen Punkten, obwohl mir mitgeteilt wird, dass dies in der nächsten Version der Fall sein wird. @RobertH hat die Verwendung von rbind vorgeschlagen, obwohl mir nicht genau klar ist, wie das funktioniert.
Mox
Es sieht so raster::unionaus, als ob es auch für die SpatialLinesDataFrame-Klasse funktioniert!
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. 
Mox
quelle