如何将空间多边形转换为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,如果它在外面。问题是is bcSpatialPolygons并且它不包含属性表。

显然要向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。
杰弗里·埃文斯

Answers:


11

“ coast”,“ ro”和“ bc”对象与您的问题有什么关系?问题可能在于您正在使用“ readShapeSpatial”。您是否在rgdal中尝试过readOGR?如果您正在读取多边形shapefile,则readOGR将导致SpatialPolygonsDataFrame对象。

如果实际上您确实有一个SpatialPolygons对象,并且想要强制转换为SpatialPolygonsDataFrame,则指定的数据框将需要使其行名与多边形插槽中的多边形ID相匹配。这是一个简单的例子。

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

我展示了其余的代码,例如“ coast”,“ ro”和“ bc”,以帮助您大致了解我想做的事情。我需要得到我所要问的更多答案,使用我自己的变量以使其更易于理解是明智的选择。另外,readOGR和readShapeSpatial怎么处理?“ bc”包含道路缓冲区,这是我需要向其添加新列的空间多边形对象,因此我必须先将其转换为spatialPolygonsDataFrame。
gsa 2015年

10

尝试:

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

match.ID 避免了匹配多边形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" 

当出现错误:“数据行名称与多边形ID不匹配”时,此解决方案似乎很有帮助:重命名数据框的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(polygons)。您的示例将对象强制为同一类。此外,在实际示例中,您会引发错误,因为数据框的行名与多边形插槽中的ID不匹配。您需要拉出多边形ID,然后在强制之前将其分配给行名。
杰弗里·埃文斯

@JeffreyEvans,这是工作代码中的复制粘贴。没有错误,一切正常。只需阅读一些有关如何SpatialPolygonsDataFrame创建的文档。
SS_Rebelious

4
但是,由于在示例中使用了readOGR,因此从SpatialPolygonsDataFrame开始,并且子集所包含的数据帧已经具有正确的行名,因为它是从原始sp对象中提取的。这是一个稻草人的例子。
Jeffrey Evans

@JeffreyEvans,我编辑了答案以阐明含义。
SS_Rebelious 2015年

看到我在主帖子中的最后编辑,并告诉我我做错了什么,原因是我认为我根据您的评论做了,但它给出了错误。使用我自己的变量使其更易于理解。谢谢
gsa 2015年

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)

由于dfspatial_df是数据帧对象,列可以容易地添加

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.