通过R中的属性将SpatialPolygonsDataFrame子集化(即删除多边形)的简单方法


75

我想简单地基于@data数据框中的相应属性值从SpatialPolygonsDataFrame对象中删除一些多边形,以便我可以绘制一个简化的/细分的shapefile。到目前为止,我还没有找到一种方法来做到这一点。

例如,假设我要从此世界shapefile中删除所有面积小于30000的多边形。我该怎么做?

或者,类似地,我该如何删除Antartica?

require(maptools)

getinfo.shape("TM_WORLD_BORDERS_SIMPL-0.3.shp") 
# Shapefile type: Polygon, (5), # of Shapes: 246
world.map <- readShapeSpatial("TM_WORLD_BORDERS_SIMPL-0.3.shp")

class(world.map)
# [1] "SpatialPolygonsDataFrame"
# attr(,"package")
# [1] "sp"

head(world.map@data)
#   FIPS ISO2 ISO3 UN                NAME   AREA  POP2005 REGION SUBREGION     LON     LAT
# 0   AC   AG  ATG 28 Antigua and Barbuda     44    83039     19        29 -61.783  17.078
# 1   AG   DZ  DZA 12             Algeria 238174 32854159      2        15   2.632  28.163
# 2   AJ   AZ  AZE 31          Azerbaijan   8260  8352021    142       145  47.395  40.430
# 3   AL   AL  ALB  8             Albania   2740  3153731    150        39  20.068  41.143
# 4   AM   AM  ARM 51             Armenia   2820  3017661    142       145  44.563  40.534
# 5   AO   AO  AGO 24              Angola 124670 16095214      2        17  17.544 -12.296

如果我做这样的事情,该图将不会反映任何变化。

world.map@data = world.map@data[world.map@data$AREA > 30000,]
plot(world.map)

如果执行此操作,将得到相同的结果:

world.map@data = world.map@data[world.map@data$NAME != "Antarctica",]
plot(world.map)

任何帮助表示赞赏!

Answers:


71

看起来您正在覆盖数据,但没有删除多边形。如果要削减包括数据和面的数据集,请尝试例如

world.map <- world.map[world.map$AREA > 30000,]
plot(world.map)

[[2016年4月19日编辑]]该解决方案曾经有效,但@Bonnie报告了较新的R版本(尽管数据也有所更改?): world.map <- world.map[world.map@data$AREA > 30000, ] 如果有帮助,请支持@Bonnie的回答。


如此简单,但现在我知道了。谢谢!
baha-kev 2012年

1
正是我过去两天试图弄清楚的东西。谢谢!
chryss 2013年

两种解决方案(您和Bonnie的解决方案)都对我
有用

39

当我尝试在R 3.2.1中执行此操作时,以上的tim riffe的技术对我不起作用,尽管对其进行了一些修改可以解决该问题。我发现在指定子集的属性之前,我还必须专门引用数据槽,如下所示:

world.map <- world.map[world.map@data$AREA > 30000, ]
plot(world.map)

如果其他人遇到相同的问题,则将其添加为替代答案。


使用最新的R版本,@data当我以这种方式对数据进行子集处理时,我会迷失方向。该Formal Class SpatialPolygonsDataFrameFormal Class SpatialPolygons。这是否也发生在您身上?
蒂姆·乌德勒支(Tim_Utrecht)

这里同样的问题。您找到解决方案了吗?
塞弗林

1
我没有使用过较新的R版本,但您可以在下面尝试使用Erick Chacon的建议(使用subset
Bonnie,

16

仅需提一下,这subset也使工作避免在条件下写数据的名称。

world.map <- subset(world.map, AREA > 30000)
plot(world.map)

是的,正是这个命令对我不起作用。还适合您吗?
第5次

对我来说,使用subset命令是我能够在并行化(降雪)环境下对空间数据进行子集化的唯一方法。
卢卡斯·佛提尼

11

我使用以上技术制作了仅澳大利亚的地图:

australia.map < - world.map[world.map$NAME == "Australia",]
plot(australia.map)

事实证明,“澳大利亚”之后的逗号很重要。

这种方法的一个缺点是,它似乎保留了所有其他国家/地区的所有属性列和行,而只是将它们填充为零。我发现,如果我写出.shp文件,然后使用readOGR(rgdal包)读回它,它将自动删除空的地理数据。然后,我可以只用我想要的数据编写另一个形状文件。

writeOGR(australia.map,".","australia",driver="ESRI Shapefile")
australia.map < - readOGR(".","australia")
writeOGR(australia.map,".","australia_small",driver="ESRI Shapefile")

至少在我的系统上,是使用“读取”功能删除了空数据,因此我必须在读回一次文件后再写该文件(如果尝试重用文件名,则会出现错误)。我敢肯定有一种更简单的方法,但是对于我来说,这似乎已经足够好了。


2
本注释所述, R不会自动删除未使用的因子水平,而是您必须重新分解:feature$ATTR <- factor(feature$ATTR)
不同的本

逗号很重要,因为它暗示了一个选择:在逗号之前,我们选择行(NAME等于Austrialia的所有行),在逗号之后,我们选择列,此处:由于未指定特定列,因此是所有列。
理查德

@adifferentben会不会droplevels()是一个更好的选择?
Nicola Pasquino 2015年

1

作为第二指针:这并不能用于与形状的“孔” shape文件的工作,因为它是由指数子集。

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.