Konvertieren eines räumlichen Polygons in einen SpatialPolygonsDataFrame und Hinzufügen einer Spalte zur Attributtabelle

19
coast<-readShapeSpatial("coastline.shp")
landc<-readShapeSpatial("landcover.shp")
ro<-readShapeSpatial("roads.shp")
bc<-gBuffer(ro,width=100)
landc$ratings=1
landc$ratings[landc$LANDUSE_ID==4]=0 

Oben nehme ich eine Kategorie mit 4 und setze sie in der neuen Spalte als 0.

An dieser Stelle möchte ich die Spalte ratingsauch für die benennen bc, wo es 0 nehmen wird, wenn es innerhalb des Puffers ist und 1, wenn es außerhalb ist. Das Problem ist, dass das bcist SpatialPolygonsund es nicht die Attributtabelle enthält.

Um einem SpatialPolygonObjekt eine Spalte hinzuzufügen, muss man sie natürlich in eine konvertieren SpatialPolygonsDataFrame, aber ich weiß nicht, wie.

Ich habe es versucht:

buf_df<-as.data.frame(bc)
s_po<-SpatialPolygonsDataFrame(bc,buf_df)
s_po$ratings=0

aber dieser Fehler taucht auf:

row.names of data and Polygons IDs do not match 
gsa
quelle
1
Wenn Sie die Hilfe für gBuffer lesen, wissen Sie, dass bei byid = TRUE das Ergebnis ein SpatialPolygonsDataFrame ist.
Jeffrey Evans

Antworten:

11

Was haben die Objekte "coast", "ro" und "bc" mit Ihrem Problem zu tun? Das Problem kann darin liegen, dass Sie "readShapeSpatial" verwenden. Hast du readOGR in rgdal ausprobiert? Wenn Sie ein Polygon-Shapefile lesen, führt readOGR zu einem SpatialPolygonsDataFrame-Objekt.

Wenn Sie tatsächlich über ein SpatialPolygons-Objekt verfügen und in SpatialPolygonsDataFrame konvertieren möchten, müssen die Rownamen des angegebenen Datenrahmens mit den Polygon-IDs im Polygon-Slot übereinstimmen. Hier ist ein kurzes Beispiel.

library(sp)

# create some SpatialPolygons with ID's "2" and "3"
( p <- SpatialPolygons(list(Polygons(list(Polygon(cbind(c(2,4,4,1,2),c(2,3,5,4,2)))), "2"),
     Polygons(list(Polygon(cbind(c(5,4,2,5),c(2,3,2,2)))), "3"))) )
class(p)    

# Create a dataframe and display default rownames
( p.df <- data.frame( ID=1:length(p)) ) 
rownames(p.df)

# Try to coerce to SpatialPolygonsDataFrame (will throw error)
p <- SpatialPolygonsDataFrame(p, p.df) 

# Extract polygon ID's
( pid <- sapply(slot(p, "polygons"), function(x) slot(x, "ID")) )

# Create dataframe with correct rownames
( p.df <- data.frame( ID=1:length(p), row.names = pid) )    

# Try coersion again and check class
 p <- SpatialPolygonsDataFrame(p, p.df)
 class(p) 

# Now we can add a column
p@data$ratings <- 1:2 

# Or modify an existing one
p[p$ID < 2 ,] <- 5
Jeffrey Evans
quelle
Ich habe den Rest des Codes wie "coast", "ro" und "bc" gezeigt, damit Sie einen Eindruck davon bekommen, was ich generell versuche. Ich brauche eine genauere Antwort auf meine Fragen und es wäre ratsam, meine eigenen Variablen zu verwenden, um verständlicher zu sein. Plus, was ist mit dem readOGR und dem readShapeSpatial? Das "bc" enthält den Straßenpuffer, der das räumliche Polygonobjekt ist, zu dem ich die neue Spalte hinzufügen muss, daher muss ich es zuerst in ein räumliches Polygon-Datenframe konvertieren.
gsa
10

Versuchen:

#Code taken from the question:
s_po <- SpatialPolygonsDataFrame(bc, buf_df, match.ID = F) 

match.ID Vermeidet das Erfordernis von Rownamen für Match Polygons ID

Fabián
quelle
4
Seien Sie nicht gegenteilig, es wird nicht geschätzt! Der Grund, warum "komplizierte" Antworten bereitgestellt wurden, ist, dass 2015, als die Frage beantwortet wurde, das match.ID-Argument in der Coversion-Methode nicht verfügbar war.
Jeffrey Evans
7

Es ist ganz einfach:

library("rgdal")
polygons <- readOGR('path_to/file.shp',
                      layer = 'file')
class(polygons)
>[1] "SpatialPolygonsDataFrame"
>attr(,"package")
>[1] "sp"

poly_df <- as.data.frame(polygons)
# do some staff with "poly_df" that doesn't support SpatialPolygonsDataFrame
# then convert it to SPDF back again
s_poly <- SpatialPolygonsDataFrame(polygons, poly_df)
# add new column to SPDF:
s_poly$new_column <- "some data" 

Wenn der Fehler "row.names of data und Polygons IDs stimmen nicht überein" auftritt, scheint diese Lösung hilfreich zu sein: Benennen Sie die IDs des Datenrahmens um, damit sie mit den IDs der Polygone übereinstimmen:

newdata <- data.frame(whatever you want in here)
row.names(newdata) <- (however the new polygons are labeled)
polygons <- SpatialPolygonsDataFrame(polygons, newdata)
SS_Rebelious
quelle
2
Ich bin mir nicht sicher, ob ich hier ein paar Schritte machen soll. Dieser Zwang ist zweifelhaft: as.data.frame (Polygone). Ihr Beispiel zwingt das Objekt in dieselbe Klasse. Außerdem würden Sie in einem realen Beispiel einen Fehler auslösen, da die Namen der Datenrahmen nicht mit der ID in den Polygonschlitzen übereinstimmen würden. Sie müssen die Polygon-IDs ziehen und sie den Rownamen zuweisen, bevor Sie Zwang ausüben.
Jeffrey Evans
@ JeffreyEvans, dies ist ein Kopieren-Einfügen aus dem Arbeitscode. Keine Fehler, alles funktioniert. Lesen Sie einfach die Dokumentation zur Erstellung SpatialPolygonsDataFrame.
SS_Rebelious
4
Da Sie in Ihrem Beispiel jedoch readOGR verwenden, beginnen Sie mit einem SpatialPolygonsDataFrame, und der von Ihnen untergeordnete Datenrahmen weist bereits die richtigen Rownamen auf, da Sie ihn aus dem ursprünglichen sp-Objekt gezogen haben. Es ist ein Strohmann-Beispiel.
Jeffrey Evans
@ JeffreyEvans, ich habe meine Antwort bearbeitet, um die Bedeutung zu klären.
SS_Rebelious
Sehen Sie sich meine letzte Änderung im Hauptbeitrag an und sagen Sie mir, was ich falsch gemacht habe, weil ich glaube, ich habe es gemäß Ihrem Kommentar gemacht, aber es gibt einen Fehler. Benutze meine eigenen Variablen, um es verständlicher zu machen. Danke
gsa
0

Ich finde, dass die folgende Lösung im Allgemeinen funktioniert.

Erstellen Sie zunächst einen leeren Datenrahmen mit der ID als Feld:

df <- data.frame(ID=character(), stringsAsFactors=FALSE )

Dann erhalten Sie die IDs des räumlichen Polygons bc:

for (i in bc@polygons ) { df <- rbind(df, data.frame(ID=i@ID, stringsAsFactors=FALSE))  }
# and set rowname=ID
row.names(df) <- df$ID

Verwenden Sie dann df als zweites Argument für die Konvertierungsfunktion für räumliche Datenrahmen:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

Wie dfund spatial_dfDataframe - Objekte sind, können Spalten leicht hinzugefügt werden

user55570
quelle