Home > Mobile >  Spatial equivalent of "floor" for geometries or coordinates in sf dataframe
Spatial equivalent of "floor" for geometries or coordinates in sf dataframe

Time:05-10

I have buoy data for several locations where temperature and salinity were recorded. It is in a spatial dataframe:

The data shown below are all from the same buoy.

> head(CB_noaa_TS_2018_2021)
Simple feature collection with 6 features and 3 fields
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: -76.4432 ymin: 38.97071 xmax: -76.44319 ymax: 38.97074
CRS:           NA
# A tibble: 6 × 4
  date_time           Temperature Salinity             geometry
  <dttm>                    <dbl>    <dbl>              <POINT>
1 2018-07-01 01:00:00        26.9     7.28  (-76.4432 38.97073)
2 2018-07-01 02:00:00        26.8     7.29 (-76.44319 38.97074)
3 2018-07-01 03:00:00        26.8     7.31  (-76.4432 38.97074)
4 2018-07-01 04:00:00        26.9     7.37  (-76.4432 38.97073)
5 2018-07-01 05:00:00        27.4     7.34  (-76.4432 38.97071)
6 2018-07-01 09:00:00        26.7     7.32  (-76.4432 38.97074)

There are several buoys in this dataset which are many km apart; however, due to slight changes in position over time (meters), the coordinates (from GPS) fluctuate making it appear like many hundreds of separate locations. I would like to group these precise locations into a general location for each buoy.

Is there a spatial equivalent to Lubridate's "floor_date" where I can round the coordinates or some other way to drop some precision on the coordinates?

CodePudding user response:

I think you're looking for st_centroid, which can be used to calculate the spatial average of a group of points. You can use it like this:

library(tidyverse)

CB_noaa_TS_2018_2021 %>%
  mutate(geometry = st_centroid(st_combine(geometry)))
#> Simple feature collection with 6 features and 3 fields
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -76.4432 ymin: 38.97073 xmax: -76.4432 ymax: 38.97073
#> CRS:           NA
#>             date_time Temperature Salinity                  geometry
#> 1 2018-07-01 01:00:00        26.9     7.28 POINT (-76.4432 38.97073)
#> 2 2018-07-01 02:00:00        26.8     7.29 POINT (-76.4432 38.97073)
#> 3 2018-07-01 03:00:00        26.8     7.31 POINT (-76.4432 38.97073)
#> 4 2018-07-01 04:00:00        26.9     7.37 POINT (-76.4432 38.97073)
#> 5 2018-07-01 05:00:00        27.4     7.34 POINT (-76.4432 38.97073)
#> 6 2018-07-01 09:00:00        26.7     7.32 POINT (-76.4432 38.97073)

You can see what this does visually by plotting the original points in black and the averaged points in red:

CB_noaa_TS_2018_2021 %>%
  pluck(4) %>%
  plot()

CB_noaa_TS_2018_2021 %>%
  mutate(geometry = st_centroid(st_combine(geometry))) %>%
  pluck(4) %>%
  plot(col = "red", add = TRUE)

enter image description here


Reproducible version of data

library(sf)

CB_noaa_TS_2018_2021 <- st_sf(structure(list(date_time = structure(
  c(1530406800, 1530410400, 
1530414000, 1530417600, 1530421200, 1530435600), class = c("POSIXct", 
"POSIXt"), tzone = ""), Temperature = c(26.9, 26.8, 26.8, 26.9, 
27.4, 26.7), Salinity = c(7.28, 7.29, 7.31, 7.37, 7.34, 7.32), 
    geometry = structure(list(structure(c(-76.4432, 38.97073), class = c("XY", 
    "POINT", "sfg")), structure(c(-76.44319, 38.97074), class = c("XY", 
    "POINT", "sfg")), structure(c(-76.4432, 38.97074), class = c("XY", 
    "POINT", "sfg")), structure(c(-76.4432, 38.97073), class = c("XY", 
    "POINT", "sfg")), structure(c(-76.4432, 38.97071), class = c("XY", 
    "POINT", "sfg")), structure(c(-76.4432, 38.97074), class = c("XY", 
    "POINT", "sfg"))), class = c("sfc_POINT", "sfc"), precision = 0,
    bbox = structure(c(xmin = -76.4432, ymin = 38.97071, xmax = -76.44319, 
    ymax = 38.97074), class = "bbox"), crs = structure(list(input = 
    NA_character_, wkt = NA_character_), class = "crs"), n_empty = 0L)), 
    row.names = c("1", "2", "3", "4", "5", "6"), class = "data.frame"))

CB_noaa_TS_2018_2021
#> Simple feature collection with 6 features and 3 fields
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -76.4432 ymin: 38.97071 xmax: -76.44319 ymax: 38.97074
#> CRS:           NA
#>             date_time Temperature Salinity                   geometry
#> 1 2018-07-01 01:00:00        26.9     7.28  POINT (-76.4432 38.97073)
#> 2 2018-07-01 02:00:00        26.8     7.29 POINT (-76.44319 38.97074)
#> 3 2018-07-01 03:00:00        26.8     7.31  POINT (-76.4432 38.97074)
#> 4 2018-07-01 04:00:00        26.9     7.37  POINT (-76.4432 38.97073)
#> 5 2018-07-01 05:00:00        27.4     7.34  POINT (-76.4432 38.97071)
#> 6 2018-07-01 09:00:00        26.7     7.32  POINT (-76.4432 38.97074)

Created on 2022-05-09 by the reprex package (v2.0.1)

  • Related