The same question is asked here: https://stackoverflow.com/questions/49294933/r-convert-output-from-sfst-within-to-vector but I thought this might be a more suitable place for GIS related questions.

Im trying to use the sf package in R to see if sf object is within another sf object with the st_within function. My issue is with the output of this function which is sparse geometry binary predicate - sgbp and I need a vector as an output so that I can use the dplyr package afterwards for filtering. Here is a simplified example:

# object 1: I will test if it is inside object 2
df <- data.frame(lon = c(2.5, 3, 3.5), lat = c(2.5, 3, 3.5), var = 1) %>% 
st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) %>%
  summarise(var = sum(var), do_union = F) %>% st_cast("LINESTRING")

# object 2: I will test if it contains object 1
box <- data.frame(lon = c(2, 4, 4, 2, 2), lat = c(2, 2, 4, 4,2), var = 1) %>%
  st_as_sf(coords = c("lon", "lat"), dim = "XY") %>% st_set_crs(4326) %>% 
  summarise(var = sum(var), do_union = F) %>% st_cast("POLYGON")

# test 1
df$indicator <- st_within(df$geometry, box$geometry) # gives geometric binary predicate on pairs of sf sets which cannot be used 
df <- df %>% filter(indicator == 1)

This gives Error: Column indicator must be a 1d atomic vector or a list.

I tried solving this problem below:

# test 2
df$indicator <- st_within(df$geometry, box$geometry, sparse = F) %>% 
  diag() # gives matrix that I convert with diag() into vector
df <- df %>% filter(indicator == FALSE)

This works, it removes the row that contains TRUE values but the process of making a matrix is very slow for my calculations since my real data contains many observations. Is there a way to make the output of st_within a character vector, or maybe a way to convert sgbp to a character vector compatible with dplyr without making a matrix?

1 Answer 1


Here is how you can get a logical vector from sparse geometry binary predicate:

df$indicator <- st_within(df, box) %>% lengths > 0

or to subset without creating a new variable:

df <- df[st_within(df, box) %>% lengths > 0,]

I cannot test on your large dataset unfortunately but please let me know if it is faster than matrix approach.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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