1

I'm currently working with a shapefile that does not contain explicit latitude and longitude coordinates. My goal is to filter out areas with latitudes above 60 degrees. I want to delete the small area in the lower right corner, but I don't have the latitude and longitude. Can anyone suggest a code to achieve this?

The shapefile look like this:

enter image description here

This is my current code:

shapefile_path <- "/Users/langbai/Desktop/lcsd000b16a_e/lcsd000b16a_e.shp"

shapefile_data <- st_read(shapefile_path)

convex_hulls_inset <- convex_hulls_with_farms %>%
  filter(lat < 60)

shapefile_inset <- shapefile_data %>%
  filter(st_coordinates(st_centroid(geometry))[, 2] < 80)
1
  • what is \<-? you can always split the geometry column using st_coordinates(). this allows you to filter for any lon/lat you want. though you may want to be careful when using this on line/polygon geometries.
    – D.J
    Commented Jun 5 at 6:49

2 Answers 2

1

First, create a new column using mutate(), then filter() that column. Here's an example using the built-in nc dataset:

library(sf)
library(dplyr)
library(ggplot2)

# Example data
nc <- st_read(system.file("shape/nc.shp", package = "sf"))

shapefile_inset <- nc %>%
  mutate(y = st_coordinates(st_centroid(geometry))[, 2]) %>%
  filter(y < 35) %>%
  select(-y)

ggplot() + 
  geom_sf(data = nc) +
  geom_sf(data = shapefile_inset, fill = "#DF536B")

result

4
  • 1
    though elegant, i am not sure st_centroid() is a valid solution. look at the polygon right of 80°W which was not colored red, while all neighbors were.
    – D.J
    Commented Jun 5 at 6:58
  • Thank you so much for your code! I finally got the map I needed. It helped me a lot! Commented Jun 5 at 7:25
  • 1
    @D.J - absolutely, but if you examine the OP's example map, you'll note the southern Canadian provinces/territories either terminate at 60°N, or have their centroid < 60°N. In the case of the OP's data, this method is sound.
    – L Tyrone
    Commented Jun 6 at 3:01
  • 1
    Its not clear from the Q if the OP wants features split by centroid or split by having any coordinate below a threshold. Accepting the answer seems to indicate the former is sufficient. For the later you can use st_coordinates on the polygon object, test against the Y column and extract the relevant L3 column values.
    – Spacedman
    Commented Jun 8 at 6:37
0

Here's how to select based on any point in the polygon being above the threshold latitude.

Sample data:

library(sf)
nc <- st_read(system.file("shape/nc.shp", package = "sf"))

Get full matrix of X, Y and L1, L2, L3 components:

xy = st_coordinates(nc)

Now select rows of that matrix where the Y column is above the threshold:

thresh=35
above = xy[ xy[,"Y"] > thresh, ]

Then the unique values of L3 are the rows that are on or above the threshold:

row.above = unique(above[,"L3"])

And we can plot them with a line at the threshold:

plot(nc$geometry)
plot(nc$geometry[row.above], col="red", add=TRUE)
plot(nc$geometry[-row.above], col="blue", add=TRUE)
abline(h=thresh, lwd=3)

enter image description here

You can adjust the logic depending on if you want features that are completely above or completely below the threshold:

below = xy [ xy[,"Y"] < thresh, ]
row.below = unique(below[,"L3"])
plot(nc$geometry)
plot(nc$geometry[row.below], col="blue", add=TRUE)
plot(nc$geometry[-row.below], col="red", add=TRUE)
abline(h=thresh, lwd=3)

enter image description here

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