0

Put together this code to filter an sf object by geometry type as suggested by @Spacedman here

Posting here for others and for myself in case there are better ways to do this.

types <- st_geometry_type(my_sf_object)

types_df <- data.frame(types)

my_labelled_sf_object <- merge(my_sf_object, types_df,by.x=0, by.y=0, all.x=TRUE)

feature_type <-  "LINESTRING"

# value here can be any of
# GEOMETRY,POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON 
# GEOMETRYCOLLECTION, CIRCULARSTRING, COMPOUNDCURVE, CURVEPOLYGON, MULTICURVE,
# MULTISURFACE, CURVE, SURFACE, POLYHEDRALSURFACE, TIN, TRIANGLE 

my_filtered_sf_object <- labelled_layers[labelled_layers$types %in% feature_type,] 

this use of %in% seems correct but strikes me as very weird syntactically since really I'm selecting only rows with feature_type in that column rather than the other way around.

1

%in% is used to match a single value from a vector with any of the values in another vector. For example this returns TRUE if any values on the left are in the set of 2, ,5 or 12:

> (1:10) %in% c(2,5,12)
 [1] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE

If you are only testing against a single value then you can use ==, so your example should be equivalent to:

labelled_layers$types == feature_type

because feature_type is just "LINESTRING".

If you want to check against a number of geometry types with the same dimension, eg all linear features:

labelled_layers$types %in% c("LINESTRING","MULTILINESTRING")

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.