What you describe is doable within context of sf package. The only tricky part seems to be selection of polygons intersecting the outer boundary (and not those fully contained). A possible approach for this is to convert your buffer from polygon to a linestring.
For implementation consider this piece of code (adapted from an earlier blogpost on merging geometries):
library(sf)
library(dplyr)
library(ggplot2)
# NC counties as polygons - a shapefile shipped with the sf package
counties <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = T) %>%
st_transform(2264) # a feety CRS, to make it interesting :)
# three NC cities as points
points <- data.frame(name = c("Raleigh", "Greensboro", "Wilmington"),
x = c(-78.633333, -79.819444, -77.912222),
y = c(35.766667, 36.08, 34.223333)) %>%
st_as_sf(coords = c("x", "y"), crs = 4326) %>%
st_transform(2264) # transform to a feety CRS
# buffer of 50 miles around Raleigh city centre
buffer <- st_buffer(subset(points, name == "Raleigh"), 5280 * 50)
# intersection with buffer as a polygon
counties$close2raleigh <- ifelse(sf::st_intersects(counties, buffer, sparse = F),
"Yes",
"No")
ggplot() +
geom_sf(data = counties, aes(fill = close2raleigh)) +
geom_sf(data = subset(points, name == "Raleigh"), pch = 4, color = "red") +
geom_sf(data = buffer, fill = NA, color = "red") +
scale_fill_viridis_d() +
theme(legend.position = "bottom") +
labs(fill = "Close to Raleigh?")
# ring around raleigh (just the ring!)
ring <- buffer %>%
st_cast("LINESTRING")
# intersection with buffer as a linestring / edge of polygon
counties$intersects_ring <- ifelse(sf::st_intersects(counties, ring, sparse = F),
"Yes",
"No")
ggplot() +
geom_sf(data = counties, aes(fill = intersects_ring)) +
geom_sf(data = subset(points, name == "Raleigh"), pch = 4, color = "red") +
geom_sf(data = buffer, fill = NA, color = "red") +
scale_fill_viridis_d() +
theme(legend.position = "bottom") +
labs(fill = "Close to Raleigh?")