Use geometry binary predicate list to subset simple feature object?

I am trying to create a new simple feature from two overlapping features. I want to subset all polygons that are fully or partially located within my buffer (red border). However, the st_overlaps generates Sparse geometry binary predicate list. I have honestly no idea how to use this list to subset my original fc to create new geometry?. This suggestion using st_within does not work: nbrs.buff <- left[st_overlaps(buff, left) %>% lengths > 1, ], as it subset all of the files, not ones overed by buffer. What I am missing?

Here is my dummy example:

shp = system.file("shape/nc.shp", package="sf")

my.sf <- st_read(shp, quiet = TRUE)

# Convert crs to projected system to make buffer
my.sf.web<- st_transform(my.sf, 3857)

# Subset the data to create two independent shps
i = 10

# Split datasets in two files
one  = my.sf.web[i, ]
left = my.sf.web[-i,]

# Create buffer
buff = st_buffer(one, 40000 ) # distance

# CHeck which polygons overlaps with my buffer
out.overlap = st_overlaps(buff, left)

# Subset the overlapping polygons to create new geometry: DOES NOT WORK??
nbrs.buff <- left[st_overlaps(buff, left) %>% lengths  > 1, ]
• In st_overlaps you can set st_overlaps(buff,left, sparse = F) if you want an resulting sf object and not a sparse geometry list Mar 10 '20 at 13:48

buff is only a single feature. Then st_overlaps(buff, left) is a list with one element (the row numbers of the seven features it overlaps with).

Getting the first (and only) element of the list gets you the row numbers in left of the overlap. So subset that:

left[st_overlaps(buff,left)[],]

If you did the overlaps test the other way round then you get a longer list with an element for each feature in left which will be 0 for no overlaps. You can then test for any overlap to get the row index:

> which(lengths(st_overlaps(left,buff))>0)
  3 11 22 25 38 39 41

which should be the same as:

> st_overlaps(buff,left)[]
  3 11 22 25 38 39 41
• Wow @spacedman, this works!! However, can you explain why the wor numbers of nbrs.buff <- left[st_overlaps(buff,left)[],] print out by as.numeric(rownames(nbrs.buff)) are  3 12 23 26 39 40 42 and not ` 3 11 22 25 38 39 41` in you example? I wonder why there is always 3 but other numbers are increased by one, which would be logical? Thanks again! Mar 10 '20 at 11:15
• rownames are preserved on subsetting. The original data set has rownames "1" to "100". When you chop out buff at row 10 then left has 99 rownames: "1" to "9" then "11" to "100". So row 10 has rowname "11". Note I use quotes for rownames because they are character strings and not numbers. Mar 10 '20 at 11:36
• Oh, I see. Perfectly logical, that I have first removed one item. Thank you again! Mar 10 '20 at 14:58