Fusionar múltiples SpatialPolygonDataFrames en 1 SPDF en R?

22

He creado 2 polígonos en QGIS. Al usarlos en R, los polígonos se convierten automáticamente en SpatialPolygonsDataFrame (SPDF). Me gustaría fusionarlos en un solo SPDF (como es muy fácil en ArcGis usando Tool Merge ). Estoy seguro de que debería haber una manera simple de cómo completar eso en R, pero no puedo encontrar cómo. la función de fusión parece fusionar solo data.frames, la función de agregado disuelve múltiples polígonos en un shp, gIntersect (al escribir la función de unión) devuelve un valor lógico, en absoluto el SPDF.

ingrese la descripción de la imagen aquí

Los datos están disponibles aquí: 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
fuente
2
Ver? Rgeos :: gUnion y / o? Raster :: union
mdsumner

Respuestas:

21

Si no necesita fusionar la topología, pero solo agrega nuevos polígonos, simplemente puede usar:

ab <- rbind(a,b)

Si obtiene un error de "valores de ranura de ID de polígonos no únicos", significa que los nombres de fila de los objetos son los mismos. Para solucionar esto, puede usar spChFID para cambiar los nombres de fila y las relaciones de ranura asociadas. Dado que las ranuras en el objeto usan los nombres de fila para asociar el objeto, no puede simplemente cambiar row.names en la ranura @data.

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

La función union (union_sp) en el paquete ráster está haciendo esto y llamando a gIntersects desde rgeos, detrás de escena y es una función auxiliar muy conveniente.

**** Editar 08-06-2018 Hay un argumento no documentado que se puede utilizar para omitir el problema de la ID duplicada.

ab <- rbind(a, b, makeUniqueIDs = TRUE) 
Jeffrey Evans
fuente
Hola, gracias, probé este pero recibí un error: Error en validObject (res): objeto no válido de clase "SpatialPolygons": valores de ranura de ID de polígonos no únicos. ¿Cómo puedo lidiar con este error?
maycca
3
Puede hacer: ab <- bind(a, b) para evitar ese error
Robert Hijmans
raster :: union actualmente no funciona con dataframes de puntos espaciales
Mox
19

Solución súper fácil proporcionada por @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)

resultó en :

clase (ab)

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

ingrese la descripción de la imagen aquí

maycca
fuente
66
Solución súper fácil proporcionada por Robert Hijmans, el autor de raster :)
mdsumner
'Union' no funciona (actualmente) para marcos de datos de puntos espaciales, aunque me dijeron que lo hará en la próxima versión. @RobertH ha sugerido el uso de rbind, aunque no tengo muy claro cómo funciona.
Mox
¡Parece que también raster::unionfunciona para la clase 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
fuente