Як перетворити просторовий полігон в 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об'єкта, ви повинні перетворити його в 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.
Джефрі Еванс

Відповіді:


11

Що стосуються об'єктів "узбережжя", "ро" та "bc" з вашою проблемою? Проблема може полягати в тому, що ви використовуєте "readShapeSpatial". Ви спробували readOGR в rgdal? Якщо ви читаєте файл форми многокутника, readOGR призведе до об’єкта SpatialPolygonsDataFrame.

Якщо ви насправді маєте об’єкт SpatialPolygons і хочете примусити його до SpatialPolygonsDataFrame, зазначеному фрейму даних потрібно, щоб його імена рядків відповідали ідентифікаторам полігона в слоті полігонів. Ось короткий приклад.

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", щоб допомогти вам зрозуміти, що я намагаюся зробити в цілому. Мені потрібно отримати більш точну відповідь на те, що я прошу, і було б розумно використовувати мої власні змінні, щоб бути зрозумілішими.Plus, яка угода з readOGR та readShapeSpatial? "Bc" містить буфер доріг, який є об'єктом просторових полігонів, до якого мені потрібно додати новий стовпець, таким чином, я повинен спершу перетворити його в просторовий PolygonsDataFrame.
gsa

10

Спробуйте:

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

match.ID дозволяє уникнути вимоги імен рядків для ідентифікатора полігонів збігу


4
Не будьте навпаки, це не цінується! Причина "складних" відповідей була надана через те, що у 2015 році, коли було вирішено питання, аргумент match.ID не був доступний у методі примусової роботи.
Джефрі Еванс

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" 

Коли виникає помилка: "рядок.імена даних та ідентифікатори полігонів не відповідають", це рішення виявляється корисним: перейменувати ідентифікатори фрейму даних відповідно до ідентифікаторів полігонів:

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 (багатокутники). Ви, наприклад, примушуєте об'єкт до одного класу. Крім того, у реальному прикладі ви б навели помилку, оскільки назви рядків фрейму даних не відповідали б ідентифікатору в слотах (іх) полігону. Вам потрібно витягнути ідентифікатори багатокутника і призначити їх іменам рядків до примусу.
Джеффрі Еванс

@JeffreyEvans, це копія-вставлення з робочого коду. Немає помилок, все працює. Просто прочитайте деяку документацію про те, як SpatialPolygonsDataFrameстворено.
SS_Rebelious

4
Але, оскільки ви використовуєте readOGR у своєму прикладі, ви починаєте з SpatialPolygonsDataFrame, а підмножина даних, у якої ви підмножили, вже має правильні назви рядків, оскільки ви витягнули її з оригінального об'єкта sp. Це солом'яний приклад.
Джеффрі Еванс

@JeffreyEvans, я змінив свою відповідь, щоб уточнити значення.
SS_Rebelious

подивіться мою останню редакцію в головному дописі і скажіть мені, що я зробив неправильно, я думаю, що я зробив це відповідно до вашого коментаря, але це дає помилку. Використовуйте мої власні змінні, щоб зробити його більш зрозумілим. Дякую
gsa

0

Я вважаю, що наступне рішення, як правило, працює.

Спочатку створіть порожній кадр даних з ідентифікатором як поле:

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

Потім отримайте ідентифікатори просторового багатокутника 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є об'єктами фрейму даних, стовпці можна легко додати

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.