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)
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")
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$
forSpatial-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
How to Use Tidyr::Separate When the Number of Needed Variables Is Unknown
Date Format in Tooltip of Ggplotly
Converting a \U Escaped Unicode String to Ascii
Plotly: Updating Data with Dropdown Selection
Dplyr Broadcasting Single Value Per Group in Mutate
How to Pivot/Unpivot (Cast/Melt) Data Frame
How to Change the Figure Caption Format in Bookdown
How to Make Variable Bar Widths in Ggplot2 Not Overlap or Gap
Plot.New Has Not Been Called Yet
How to Export S3 Method So It Is Available in Namespace
Dplyr Issues When Using Group_By(Multiple Variables)
Rstudio Shiny Error: There Is No Package Called "Shinydashboard"