Cara mengonversi spatialpolygon ke SpatialPolygonsDataFrame dan menambahkan kolom ke tabel atribut

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 

Di atas, saya mengambil kategori apa pun yang memiliki 4 dan di kolom baru taruh sebagai 0.

Pada titik ini, saya ingin kolom dinamai ratingsjuga untuk bc, di mana ia akan mengambil 0 jika ada di dalam buffer dan 1 jika di luar. Masalahnya adalah bahwa bcis SpatialPolygonsdan itu tidak mengandung tabel atribut.

Jelas untuk menambahkan kolom ke SpatialPolygonobjek Anda harus mengubahnya menjadi SpatialPolygonsDataFrame, tapi saya tidak tahu caranya.

Saya mencoba ini:

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

tetapi kesalahan ini muncul:

row.names of data and Polygons IDs do not match 
ya
sumber
1
Nah, jika Anda membaca bantuan untuk gBuffer, Anda akan tahu bahwa jika byid = TRUE hasilnya adalah SpatialPolygonsDataFrame.
Jeffrey Evans

Jawaban:

11

Apa hubungan "pantai", "ro" dan "bc" dengan masalah Anda? Masalahnya mungkin terletak pada Anda menggunakan "readShapeSpatial". Sudahkah Anda mencoba readOGR di rgdal? Jika Anda membaca bentuk poligon, readOGR akan menghasilkan objek SpatialPolygonsDataFrame.

Jika Anda memang memiliki objek SpatialPolygons dan ingin memaksa ke dalam SpatialPolygonsDataFrame, dataframe yang ditentukan harus memiliki nama rameame yang cocok dengan ID poligon di slot poligon. Ini adalah contoh cepat.

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
sumber
saya menunjukkan sisa kode seperti "pantai", "ro" dan "bc" untuk membantu Anda mendapatkan ide tentang apa yang saya coba lakukan secara umum. saya perlu mendapatkan jawaban yang lebih langsung dari apa yang saya minta dan akan lebih bijaksana untuk menggunakan variabel saya sendiri agar lebih dimengerti. Selain itu, apa hubungannya dengan readOGR dan readShapeSpatial? "Bc" berisi buffer jalan yang merupakan objek spatialpolygons yang harus saya tambahkan kolom baru, jadi saya harus mengonversinya menjadi spatialPolygonsDataFrame terlebih dahulu.
gsa
10

Mencoba:

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

match.ID menghindari persyaratan nama pengganti untuk ID poligon pertandingan

Fabián
sumber
4
Jangan sebaliknya, itu tidak dihargai! Alasan "rumit" jawaban diberikan adalah karena pada 2015, ketika pertanyaan itu diatasi, argumen match.ID tidak tersedia dalam metode koersi.
Jeffrey Evans
7

Sederhana saja:

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" 

Ketika Kesalahan: "baris.nama data dan ID Poligon tidak cocok" muncul solusi ini tampaknya membantu: ganti nama ID dataframe agar cocok dengan ID poligon:

newdata <- data.frame(whatever you want in here)
row.names(newdata) <- (however the new polygons are labeled)
polygons <- SpatialPolygonsDataFrame(polygons, newdata)
SS_Rebelious
sumber
2
Tidak yakin tentang beberapa langkah di sini. Paksaan ini meragukan: as.data.frame (poligon). Misalnya Anda memaksa objek ke kelas yang sama. Selain itu, dalam contoh nyata Anda akan melempar kesalahan karena rownames dari dataframe tidak akan cocok dengan ID dalam slot poligon. Anda perlu menarik ID poligon dan menetapkannya ke nama belakang sebelum paksaan.
Jeffrey Evans
@ JeffreyEvans, ini adalah salin-tempel dari kode kerja. Tidak ada kesalahan, semuanya berfungsi. Cukup baca beberapa dokumentasi tentang cara SpatialPolygonsDataFramemembuatnya.
SS_Rebelious
4
Tetapi, karena Anda menggunakan readOGR dalam contoh Anda, Anda mulai dengan SpatialPolygonsDataFrame dan dataframe yang Anda atur sudah memiliki nama rame yang benar karena Anda menariknya dari objek sp asli. Ini adalah contoh stroberi.
Jeffrey Evans
@ JeffreyEvans, saya mengedit jawaban saya untuk menjelaskan artinya.
SS_Rebelious
lihat edit terakhir saya di posting utama dan katakan padaku apa yang saya lakukan salah karena saya pikir saya membuatnya sesuai dengan komentar Anda tetapi memberikan kesalahan. Gunakan variabel saya sendiri untuk membuatnya lebih mudah dipahami. Terima kasih
gsa
0

Saya menemukan solusi berikut umumnya berfungsi.

Pertama, buat kerangka data kosong dengan ID sebagai bidang:

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

Kemudian dapatkan ID poligon spasial 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

Kemudian gunakan df sebagai argumen kedua ke fungsi konversi dataframe spasial:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

Seperti dfdan spatial_dfobjek dataframe, kolom dapat dengan mudah ditambahkan

pengguna55570
sumber