Jak przekonwertować wielokąt przestrzenny na SpatialPolygonsDataFrame i dodać kolumnę do tabeli atrybutów

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 

Powyżej biorę dowolną kategorię, która ma 4, i w nowej kolumnie wpisuję ją jako 0.

W tym momencie chcę również nazwę kolumny ratingsdla bc, gdzie zajmie 0, jeśli jest w buforze i 1, jeśli jest na zewnątrz. Problem polega na tym, że bcjest SpatialPolygonsi nie zawiera tabeli atrybutów.

Oczywiście, aby dodać kolumnę do SpatialPolygonobiektu, musisz przekonwertować ją na obiekt SpatialPolygonsDataFrame, ale nie wiem jak.

Próbowałem tego:

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

ale pojawia się ten błąd:

row.names of data and Polygons IDs do not match 
gsa
źródło
1
Cóż, jeśli przeczytasz pomoc dla gBuffer, będziesz wiedział, że jeśli byid = TRUE, wynikiem jest SpatialPolygonsDataFrame.
Jeffrey Evans,

Odpowiedzi:

11

Co mają wspólnego z twoim problemem obiekty „coast”, „ro” i „bc”? Problem może polegać na tym, że używasz „readShapeSpatial”. Czy próbowałeś readOGR w rgdal? Jeśli czytasz plik kształtu wielokąta, readOGR spowoduje utworzenie obiektu SpatialPolygonsDataFrame.

Jeśli faktycznie masz obiekt SpatialPolygons i chcesz przekonać się do SpatialPolygonsDataFrame, określona ramka danych będzie musiała dopasować nazwy runa do identyfikatorów wielokątów w gnieździe wielokątów. Oto szybki przykład.

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
źródło
pokazałem resztę kodu, np. „coast”, „ro” i „bc”, aby pomóc ci zrozumieć, co ogólnie próbuję zrobić. muszę uzyskać bardziej szczegółową odpowiedź na to, o co pytam i rozsądnie byłoby użyć moich własnych zmiennych, aby były bardziej zrozumiałe. Co więcej, o co chodzi z readOGR i readShapeSpatial? „Bc” zawiera bufor dróg, który jest obiektem spatialpolygons, do którego muszę dodać nową kolumnę, dlatego muszę najpierw przekonwertować ją na spatialPolygonsDataFrame.
gsa
10

Próbować:

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

match.ID unika wymogu nazw rown dla identyfikatora wielokątów dopasowania

Fabiański
źródło
4
Nie bądź przeciwny, nie jest to doceniane! Podano „skomplikowane” odpowiedzi, ponieważ w 2015 r., Kiedy pytanie zostało rozwiązane, argument match.ID nie był dostępny w metodzie koercji.
Jeffrey Evans
7

To jest dość proste:

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" 

Gdy pojawia się błąd: „Wiersz.nazwy danych i identyfikatory wielokątów nie pasują”, to rozwiązanie wydaje się pomocne: zmień nazwy identyfikatorów ramki danych, aby dopasować identyfikatory wielokątów:

newdata <- data.frame(whatever you want in here)
row.names(newdata) <- (however the new polygons are labeled)
polygons <- SpatialPolygonsDataFrame(polygons, newdata)
SS_Rebelious
źródło
2
Nie jestem pewien na kilka kroków tutaj. Ten przymus jest wątpliwy: as.data.frame (wielokąty). Twoim przykładem jest zmuszanie obiektu do tej samej klasy. Ponadto, w prawdziwym przykładzie, wyrzuciłbyś błąd, ponieważ nazwy plików w ramce danych nie byłyby zgodne z identyfikatorem w polach szczelinowych. Musisz wyciągnąć identyfikatory wielokątów i przypisać je do nazwisk przed przymusem.
Jeffrey Evans
@JeffreyEvans, jest to kopia-wklej z działającego kodu. Bez błędów, wszystko działa. Po prostu przeczytaj dokumentację dotyczącą sposobu SpatialPolygonsDataFrametworzenia.
SS_Rebelious
4
Ale ponieważ używasz readOGR w swoim przykładzie, zaczynasz od SpatialPolygonsDataFrame, a podgrupa danych ma już prawidłowe nazwy, ponieważ wyciągnąłeś go z oryginalnego obiektu sp. Jest to przykład słomy.
Jeffrey Evans,
@JeffreyEvans, zredagowałem swoją odpowiedź, aby wyjaśnić znaczenie.
SS_Rebelious
zobacz moją ostatnią edycję w głównym poście i powiedz mi, co zrobiłem źle, bo myślę, że zrobiłem to zgodnie z twoim komentarzem, ale daje błąd. Użyj własnych zmiennych, aby uczynić go bardziej zrozumiałym. Dzięki
gsa,
0

Uważam, że następujące rozwiązanie ogólnie działa.

Najpierw utwórz pustą ramkę danych o polu ID jako:

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

Następnie uzyskaj identyfikatory wielokąta przestrzennego 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

Następnie użyj df jako drugiego argumentu do funkcji konwersji przestrzennej ramki danych:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

Ponieważ dfi spatial_dfsą obiektami ramki danych, kolumny można łatwo dodawać

użytkownik55570
źródło