Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In R & sf, how can I update coordinates of selected features?

Tags:

r

r-sf

I'm stuck with a seemingly simple problem. I'd like to manually correct the results of geocoding for selected points. Lets say that the centroid of "Dare" needs to be updated:

library(sf)     
nc <- st_centroid(st_read(system.file("shape/nc.shp", package = "sf")))
st_coordinates(filter(nc, NAME== "Dare"))

How could I change original values of

          X        Y
1 -75.80982 35.73548

Into something different?

I expected something like

st_coordinates(filter(nc, NAME== "Dare")) <- matrix(c(-73, 33), nrow = 1)

Or

nc %>% 
  mutate(geometry = ifelse(place_full_name == "Dare", 
                           yes = st_set_geometry(c(-73, 33)), 
                           no = geometry))

To do the job but both solutions produce error.


2 Answers

Use st_geometry<-.

Get original geometry (just to check):

st_geometry(nc[nc$NAME == "Dare", ])
# Geometry set for 1 feature 
# geometry type:  POINT
# dimension:      XY
# bbox:           xmin: -75.80982 ymin: 35.73548 xmax: -75.80982 ymax: 35.73548
# epsg (SRID):    4267
# proj4string:    +proj=longlat +datum=NAD27 +no_defs
# POINT (-75.80982 35.73548)

Replace selected geometry with st_geometry<-. The replacement value needs to be a simple feature geometry, hence the st_sfc(st_point(....

st_geometry(nc[nc$NAME == "Dare", ]) <-  st_sfc(st_point(c(-80, 40)))

# check again
st_geometry(nc[nc$NAME == "Dare", ])
# Geometry set for 1 feature 
# geometry type:  POINT
# dimension:      XY
# bbox:           xmin: -80 ymin: 40 xmax: -80 ymax: 40
# epsg (SRID):    4267
# proj4string:    +proj=longlat +datum=NAD27 +no_defs
# POINT (-80 40)

Note:

In the Twitter discussion shared by @radek, the author of the sf package, @Edzer Pebesma, comments that the bounding box of the original geometry isn't updated.

Original bounding box:

st_bbox(nc)
#      xmin      ymin      xmax      ymax 
# -84.05976  34.07663 -75.80982  36.49101

Replace a selected geometry with coordinates outside the original bounding box, here x less than xmin and y greater than ymax:

st_geometry(nc[nc$NAME == "Dare", ]) <-  st_sfc(st_point(c(-90, 40)))

The bbox of the object is not updated:

st_bbox(nc)
#      xmin      ymin      xmax      ymax 
# -84.05976  34.07663 -75.80982  36.49101  
like image 177
Henrik Avatar answered Oct 26 '25 10:10

Henrik


You could use st_geometry<- as in @Henrik's answer but replace the whole geometry in order to get the bounding box updated as well.

st_geometry(nc) <- st_sfc(
    ifelse(nc$NAME == "Dare", st_sfc(st_point(c(-90, 40))), nc$geometry),
    crs = st_crs(nc$geometry))

See that the bbox of the object is updated now:

st_bbox(nc)
#      xmin      ymin      xmax      ymax 
# -90.00000  34.07663 -76.02750  40.00000
like image 33
pjpjean Avatar answered Oct 26 '25 09:10

pjpjean