Simple Way to Subset Spatialpolygonsdataframe (I.E. Delete Polygons) by Attribute in R

Simple way to subset SpatialPolygonsDataFrame (i.e. delete polygons) by attribute in R

looks like you're overwriting the data, but not removing the polygons. If you want to cut down the dataset including both data and polygons, try e.g.

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

[[Edit 19 April, 2016]]
That solution used to work, but @Bonnie reports otherwise for a newer R version (though perhaps the data has changed too?):
world.map <- world.map[world.map@data$AREA > 30000, ]
Upvote @Bonnie's answer if that helped.

How to remove specific features of SpatialPolygonsDataFrame based on attributes in R?

You may subset the SpatialPolygonsDataFrame by row ids:

# row numbers of countries, exluding scandinavia
ids <- which(
!(world.map$NAME %in% c('Finland', 'Norway', 'Sweden', 'Denmark'))
)

# subset
not_scandinavia <- world.map[ids, ]

# plot
plot(not_scandinavia)

Sample Image

Subset polygons of a single spatialPolygonsDataFrame row

For "Spatial-class" objects, this kind of operation often requires some painfully low-level manipulation of the component data structures. (The larger expectation, of course, is that you'll do this once and then write a nice wrapper function of your own that does exactly what you want the next time you need it done!)

In any case, here's what that lower-level manipulation might look like in your case:

## Extract component "Polygon" objects
pp <- usa@polygons[[1]]@Polygons
## Find indices of non-Alaska Polygon objects
ii <- sapply(pp, function(X) mean(coordinates(X)[,2])<50)

## Put desired Polygon objects back together in a built-from-scratch SpatialPolygons obj.
## Note: ID will need to match row name of data.frame attached to SpatialPolygons object
USA49 <-
SpatialPolygons(list(Polygons(srl = pp[ii], ID = rownames(data.frame(usa)))),
proj4string=CRS(proj4string(usa)))
## Reattach attributes in data.frame(usa)
USA49 <- SpatialPolygonsDataFrame(USA49, data = data.frame(usa))

## Check that it worked
plot(USA49, col="lightgrey")

Sample Image

get an empty SpatialPolygonsDataFrame via subset?

Right now you can't. This is somewhat inconsistent, as for SpatialPointsDataFrame objects you can:

library(sp)
demo(meuse, ask = FALSE)
x = meuse[F,]

although with warnings; also, validObject(x) returns FALSE, so they are intended to be not allowed!

It's a bit abstract what such objects should represent, but I can see the analogy with data.frame objects with zero rows: it is useful that they can exist.

Why is it possible to use `$` to subset SpatialPolygonsDataFrame?

The short answer is that this behavior of $ is implemented by the Spatial class in the sp package, and is not a feature of general S4 object.

The long answer (how I find out about this):

  • Use showMethods("$") to find out about all the methods of the generic $.
The result shows:
Function: $ (package base)
x="C++Class"
x="envRefClass"
x="Module"
x="Raster"
x="refObjectGenerator"
x="Spatial"
x="SpatialGDAL"
x="SpatialPoints"
x="SpatialPolygonsDataFrame"
(inherited from: x="Spatial")

So we know that SpatialPolygonsDataFrame-class inherits $ from Spatial-class. We go to the root by:

  • getMethod("$", "Spatial"), which shows the implementation of $ for Spatial-class as follows:
Method Definition:

function (x, name)
{
if (!("data" %in% slotNames(x)))
stop("no $ method for object without attributes")
x@data[[name]]
}
<environment: namespace:sp>

Therefore, spatial_df$col_name is a shortcut for spatial_df@data[["col_name"]]



Related Topics



Leave a reply



Submit