วิธีการแปลง spatialpolygon เป็น SpatialPolygonsDataFrame และเพิ่มคอลัมน์ลงในตารางแอตทริบิวต์


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 

ด้านบนฉันใช้หมวดหมู่ใด ๆ ที่มี 4 และในคอลัมน์ใหม่ให้เป็น 0

ณ จุดนี้ฉันต้องการคอลัมน์ชื่อratingsเช่นกันสำหรับbcที่ซึ่งจะเป็น 0 ถ้ามันอยู่ในบัฟเฟอร์และ 1 ถ้ามันอยู่ข้างนอก ปัญหาคือว่าbcเป็นSpatialPolygonsและมันไม่ได้มีตารางคุณลักษณะ

เห็นได้ชัดว่าการเพิ่มคอลัมน์ลงในSpatialPolygonวัตถุที่คุณต้องแปลงเป็น a SpatialPolygonsDataFrameแต่ฉันไม่รู้

ฉันลองสิ่งนี้:

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

แต่ข้อผิดพลาดนี้จะปรากฏขึ้น:

row.names of data and Polygons IDs do not match 

1
ดีถ้าคุณอ่านความช่วยเหลือสำหรับ gBuffer คุณจะรู้ว่าถ้า byid = TRUE ผลที่ได้คือ SpatialPolygonsDataFrame
Jeffrey Evans

คำตอบ:


11

วัตถุ "ชายฝั่ง", "ro" และ "bc" เกี่ยวข้องกับปัญหาของคุณอย่างไร ปัญหาอาจเกิดจากการที่คุณใช้ "readShapeSpatial" คุณลอง readOGR ใน rgdal แล้วหรือยัง? หากคุณกำลังอ่านไฟล์รูปหลายเหลี่ยมรูปร่าง readOGR จะส่งผลให้วัตถุ SpatialPolygonsDataFrame

หากคุณมีวัตถุ SpatialPolygons และต้องการรวมเข้ากับ SpatialPolygonsDataFrame DataFrame ที่ระบุจะต้องมี rownames ตรงกับหมายเลขรูปหลายเหลี่ยมในสล็อตรูปหลายเหลี่ยม นี่คือตัวอย่างด่วน

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

ฉันแสดงส่วนที่เหลือของรหัสเช่น "ชายฝั่ง", "ro" และ "bc" เพื่อช่วยให้คุณเข้าใจแนวคิดของสิ่งที่ฉันพยายามทำโดยทั่วไป ฉันจำเป็นต้องได้คำตอบที่ตรงประเด็นมากขึ้นในสิ่งที่ฉันถามและควรใช้ตัวแปรของตัวเองเพื่อให้เข้าใจได้ง่ายขึ้นรวมทั้งข้อตกลงกับ readOGR และ readShapeSpatial คืออะไร "bc" มีบัฟเฟอร์ถนนซึ่งเป็นวัตถุ spatialpolygons ที่ฉันต้องการเพิ่มคอลัมน์ใหม่ไปดังนั้นฉันต้องแปลงเป็น spatialPolygonsDataFrame ก่อน
gsa

10

ลอง:

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

match.ID หลีกเลี่ยงข้อกำหนดของ rownames สำหรับการจับคู่รูปหลายเหลี่ยม ID


4
อย่าตรงกันข้ามมันไม่ได้ชื่นชม! เหตุผลที่ให้คำตอบ "ซับซ้อน" นั้นเป็นเพราะในปี 2015 เมื่อมีการตอบคำถามข้อโต้แย้งการจับคู่ ID ไม่สามารถใช้ได้ในวิธีการเล่น
Jeffrey Evans

7

มันค่อนข้างง่าย:

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" 

เมื่อข้อผิดพลาด: "row. ชื่อของข้อมูลและรูปหลายเหลี่ยมไม่ตรงกับ" เกิดขึ้นวิธีการแก้ปัญหานี้ดูเหมือนจะเป็นประโยชน์: เปลี่ยนชื่อ ID ของชื่อไฟล์เพื่อให้ตรงกับ ID ของรูปหลายเหลี่ยม:

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

2
ไม่แน่ใจในสองสามขั้นตอนที่นี่ การข่มขู่นี้น่าสงสัย: as.data.frame (รูปหลายเหลี่ยม) ตัวอย่างของคุณกำลังบีบบังคับวัตถุในคลาสเดียวกัน นอกจากนี้ในตัวอย่างจริงคุณจะเกิดข้อผิดพลาดเนื่องจากชื่อแถวของดาต้าเฟรมจะไม่ตรงกับ ID ในสล็อตรูปหลายเหลี่ยม คุณต้องดึงหมายเลขรูปหลายเหลี่ยมและกำหนดให้กับชื่อแถวก่อนการบีบบังคับ
Jeffrey Evans

@JeffreyEvans นี่คือการคัดลอกวางจากรหัสการทำงาน ไม่มีข้อผิดพลาดทุกอย่างทำงานได้ เพียงอ่านเอกสารเกี่ยวกับวิธีการSpatialPolygonsDataFrameสร้าง
SS_Rebelious

4
แต่เนื่องจากคุณใช้ readOGR ในตัวอย่างของคุณคุณจะเริ่มต้นด้วย SpatialPolygonsDataFrame และ dataframe ที่คุณเซ็ตย่อยมีชื่อแถวที่ถูกต้องอยู่แล้วเพราะคุณดึงมันจากวัตถุ sp ต้นฉบับ มันเป็นตัวอย่างชาวฟาง
Jeffrey Evans

@JeffreyEvans ฉันแก้ไขคำตอบของฉันเพื่อชี้แจงความหมาย
SS_Rebelious

ดูการแก้ไขล่าสุดของฉันในโพสต์หลักและบอกฉันว่าฉันทำอะไรผิดเพราะฉันคิดว่าฉันทำตามความคิดเห็นของคุณ แต่มันให้ข้อผิดพลาด ใช้ตัวแปรของฉันเองเพื่อให้เข้าใจได้มากขึ้น ขอบคุณ
gsa

0

ฉันพบว่าโซลูชันต่อไปนี้ใช้งานได้ปกติ

ขั้นแรกสร้างดาต้าเฟรมว่างที่มี ID เป็นฟิลด์:

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

จากนั้นรับ ID ของรูปหลายเหลี่ยมเชิงพื้นที่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

จากนั้นใช้ df เป็นอาร์กิวเมนต์ตัวที่สองของฟังก์ชั่นการแปลงข้อมูลเชิงพื้นที่:

spatial_df <- SpatialPolygonsDataFrame(bc, df)

ในฐานะที่เป็นdfและspatial_dfเป็นวัตถุ dataframe คอลัมน์สามารถเพิ่มได้อย่างง่ายดาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.