Bir spatialpolygon'u bir SpatialPolygonsDataFrame'e dönüştürme ve öznitelik tablosuna bir sütun ekleme


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 

Yukarıda, 4 olan herhangi bir kategoriyi alıyorum ve yeni sütuna 0 olarak koyuyorum.

Bu noktada, ben de arabellek içinde 0 ve dışarıda ise 1 alacak sütun ratingsiçin de adlandırılmış istiyorum bc. Sorun olduğunu bcolduğunu SpatialPolygonsve nitelik tablo içermiyor.

Açıkçası bir SpatialPolygonnesneye bir sütun eklemek için onu bir dönüştürmek zorunda SpatialPolygonsDataFrame, ama nasıl bilmiyorum.

Bunu denedim:

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

ancak bu hata ortaya çıkar:

row.names of data and Polygons IDs do not match 

1
Eğer gBuffer için yardımı okursanız, byid = TRUE ise sonucun bir SpatialPolygonsDataFrame olduğunu bilirsiniz.
Jeffrey Evans

Yanıtlar:


11

"Sahil", "ro" ve "bc" nesnelerinin sorununuzla ne ilgisi var? Sorun "readShapeSpatial" kullandığınızdan kaynaklanıyor olabilir. Rgdal'da readOGR'yi denediniz mi? Bir çokgen şekil dosyası okuyorsanız, readOGR bir SpatialPolygonsDataFrame nesnesiyle sonuçlanır.

Aslında, bir SpatialPolygons nesneniz varsa ve SpatialPolygonsDataFrame öğesine zorlamak istiyorsanız, belirtilen veri çerçevesinin rown adlarının çokgen yuvasındaki çokgen kimlikleriyle eşleşmesi gerekir. İşte kısa bir örnek.

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

i genel olarak ne yapmaya çalışıyorum hakkında fikir almak için "sahil", "ro" ve "bc" gibi kodun geri kalanını gösterdi. i soruyorum ne nokta cevap daha almak gerekir ve daha anlaşılır olması için kendi değişkenleri kullanmak akıllıca olacaktır.Plus, readOGR ve readShapeSpatial ile anlaşma nedir? "Bc" yeni sütun eklemek için gereken spatialpolygons nesne olan yollar tampon içerir, bu yüzden önce bir spatialPolygonsDataFrame dönüştürmek zorunda.
gsa

10

Deneyin:

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

match.ID eşleşen çokgenler kimliği için rownames gereksinimini önler


4
Aksine, takdir edilmez! "Karmaşık" yanıtların verilmesinin nedeni, 2015 yılında, sorunun ele alındığı zaman, match.ID argümanının baskı yönteminde bulunmamasıdır.
Jeffrey Evans

7

Oldukça basit:

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" 

Hata: "veri.ve Çokgen Kimliklerinin row.names eşleşmediği" ortaya çıktığında bu çözüm faydalı görünüyor : veri çerçevesinin kimliklerini çokgenlerin kimlikleriyle eşleştirmek için yeniden adlandırın:

newdata <- data.frame(whatever you want in here)
row.names(newdata) <- (however the new polygons are labeled)
polygons <- SpatialPolygonsDataFrame(polygons, newdata)

2
Burada birkaç adım emin değilim. Bu baskı şüphelidir: as.data.frame (çokgenler). Örneğin, nesneyi aynı sınıfa zorlamaktır. Ayrıca, gerçek bir örnekte, veri çerçevesinin rown adları çokgen yuvalarındaki (kimlikleri) kimlikle eşleşmeyeceği için bir hata atarsınız. Çokgen kimliklerini çekmeniz ve zorlamadan önce bunları rown adlarına atamanız gerekir.
Jeffrey Evans

@JeffreyEvans, bu çalışma kodundan bir kopyala yapıştır. Hata yok, her şey çalışıyor. Nasıl SpatialPolygonsDataFrameyaratıldığına dair bazı belgeleri okuyun .
SS_Rebelious

4
Ancak, örneğinizde readOGR kullandığınız için, bir SpatialPolygonsDataFrame ile başlıyorsunuz ve alt küme verdiğiniz veri çerçevesi, orijinal sp nesnesinden aldığınız için zaten doğru rown adlarına sahip. Bir strawman örneğidir.
Jeffrey Evans

@JeffreyEvans, anlamını açıklığa kavuşturmak için cevabımı düzenledim.
SS_Rebelious

ana yazı benim son düzenleme görmek ve ne yanlış söyle bana çünkü ben yorumunuza göre düşünüyorum ama hata verir düşünüyorum. Daha anlaşılır hale getirmek için kendi değişkenlerimi kullanın. Teşekkürler
GSA

0

Aşağıdaki çözüm genellikle işe yarıyor.

İlk olarak, alan olarak kimliği olan boş bir veri çerçevesi oluşturun:

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

Sonra uzamsal poligonun kimliklerini alın 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

Ardından, uzamsal veri çerçevesi dönüştürme işlevinin ikinci argümanı olarak df'yi kullanın:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

Dataframe nesneleri olarak dfve spatial_dfolduklarından, sütunlar kolayca eklenebilir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.