Fusion de plusieurs SpatialPolygonDataFrames en 1 SPDF dans R?

22

J'ai créé 2 polygones dans QGIS. En les utilisant dans R, les polygones deviennent automatiquement SpatialPolygonsDataFrame (SPDF). Je voudrais les fusionner en un seul SPDF (comme c'est très facile dans ArcGis en utilisant Tool Merge ). Je suis sûr qu'il devrait y avoir un moyen simple de compléter cela dans R, mais je ne trouve pas comment. la fonction de fusion semble fusionner uniquement data.frames, la fonction d' agrégation dissout plusieurs polygones en un seul shp, gIntersect (en tapant la fonction join) renvoie une valeur logique, pas du tout le SPDF.

entrez la description de l'image ici

les données sont disponibles ici: 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
la source
2
Voir? Rgeos :: gUnion et / ou?
Raster

Réponses:

21

Si vous n'avez pas besoin de fusionner la topologie, mais simplement d'ajouter de nouveaux polygones, vous pouvez simplement utiliser:

ab <- rbind(a,b)

Si vous obtenez une erreur «Valeurs d'emplacement d'ID de polygone non uniques», cela signifie que les noms des objets sont les mêmes. Pour résoudre ce problème, vous pouvez utiliser des spChFID pour modifier les noms de domaine et les relations d'emplacement associées. Étant donné que les emplacements de l'objet utilisent les noms de domaine pour associer l'objet, vous ne pouvez pas simplement modifier row.names dans l'emplacement @data.

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

La fonction union (union_sp) du package raster procède ainsi et appelle gIntersects à partir de rgeos, en arrière-plan et est une fonction d'aide très pratique.

**** Edit 08-06-2018 Il existe un argument non documenté qui peut être utilisé pour ignorer le problème d'ID en double.

ab <- rbind(a, b, makeUniqueIDs = TRUE) 
Jeffrey Evans
la source
Salut, merci, j'ai essayé celui-ci mais j'ai une erreur: Erreur dans validObject (res): objet de classe "SpatialPolygons" invalide: valeurs d'emplacement Polygons ID non uniques. Comment puis-je gérer cette erreur?
Maycca du
3
Vous pouvez faire: ab <- bind(a, b) pour éviter cette erreur
Robert Hijmans
raster :: union ne fonctionne pas actuellement avec spatialPOINTSdataframes
Mox
19

Solution super facile fournie par @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)

a donné lieu à:

classe (ab)

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

entrez la description de l'image ici

maycca
la source
6
Solution super facile fournie par Robert Hijmans, l'auteur de raster :)
mdsumner
'Union' ne fonctionne pas (actuellement) pour les points de données spatiaux, bien que l'on me dise que ce sera le cas dans la prochaine version. @RobertH a suggéré l'utilisation de rbind, bien que je ne sache pas exactement comment cela fonctionne.
Mox
Il semble que cela raster::unionfonctionne aussi pour la classe 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. 
Mox
la source