0

I am creating a nested sampling design.

Is it possible to calculate the distance between each and every one of my 200 sampling locations (longitude/latitude)? I would like to calculate where the distances occur on the lag line (e.g how many samples are separated by 1m,10m,100m etc) to check that there is sufficient amount of points at each distance.

Is this possible in r or any other free software?

  • One option is `sf::st_distance`. Returns a matrix with distances between every input point. – nniloc Oct 04 '22 at 03:16
  • 1
    If you want a more specific example it is best to share some of your data using `dput`. A few more hints about how to ask a great question here: https://stackoverflow.com/q/5963269/12400385 – nniloc Oct 04 '22 at 03:19

1 Answers1

0

Let's use sf::st_distance() suggested by @nniloc

Let's prepare sample occurrence data:

occ <- rgbif::occ_data(
  scientificName = "Calystegia pulchra", 
  country = "GB", 
  hasCoordinate = TRUE
)

occ <- head(occ$data, 220) |>
  sf::st_as_sf(coords = c("decimalLongitude", "decimalLatitude"), crs = 4326) |>
  subset(select = c("key", "scientificName"))

Let's create a distance matrix

m <- sf::st_distance(occ)
m[1:4, 1:4]
#> Units: [m]
#>          [,1]      [,2]      [,3]     [,4]
#> [1,]      0.0 127215.11 202758.86 763395.9
#> [2,] 127215.1      0.00  98557.85 681999.6
#> [3,] 202758.9  98557.85      0.00 583484.0
#> [4,] 763395.9 681999.59 583484.00      0.0

and function, which takes the row, and calculates how much entries where the distance > ...

how_much <- function(matrix = m, row = 1, distance = 100000) {
  length(which({{matrix}}[{{row}},] > units::as_units({{distance}}, "m")))
  }

how_much(m, 2, 100000)
#> [1] 195

Let's add it to our occurrence data:

occ |>
  dplyr::mutate(row_number = dplyr::row_number()) |>
  dplyr::rowwise() |>
  dplyr::mutate(dist_200000 = how_much(m, row_number, 200000))
#> Simple feature collection with 220 features and 4 fields
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -7.978369 ymin: 49.97314 xmax: 1.681262 ymax: 57.90633
#> Geodetic CRS:  WGS 84
#> # A tibble: 220 × 5
#> # Rowwise: 
#>    key        scientificName                       geometry row_number dist_20…¹
#>  * <chr>      <chr>                             <POINT [°]>      <int>     <int>
#>  1 3320924569 Calystegia pulchra Brum…  (-0.17902 51.49553)          1       196
#>  2 3437494613 Calystegia pulchra Brum… (-1.962333 51.78564)          2       158
#>  3 3785877810 Calystegia pulchra Brum…  (-2.541045 52.5979)          3       146
#>  4 3352641836 Calystegia pulchra Brum… (-6.189535 57.41207)          4       171
#>  5 3338086543 Calystegia pulchra Brum… (-2.302697 53.20301)          5       154
#>  6 3352720276 Calystegia pulchra Brum…  (-3.052632 54.8225)          6       147
#>  7 3352736637 Calystegia pulchra Brum… (-1.614114 55.37932)          7       164
#>  8 3384449063 Calystegia pulchra Brum… (-4.681922 57.14801)          8       135
#>  9 3421262904 Calystegia pulchra Brum…  (-6.19056 57.42103)          9       171
#> 10 3392248456 Calystegia pulchra Brum… (-6.159327 56.11731)         10       158
#> # … with 210 more rows, and abbreviated variable name ¹​dist_200000

Regards, Grzegorz

Created on 2022-10-04 with reprex v2.0.2

Grzegorz Sapijaszko
  • 1,913
  • 1
  • 5
  • 12
  • Thank you very much!! Do the co-ordinates have to be in degrees? Can it be in decimal degrees: E.g. here are some of my points: 1A 169.5937478°E 45.6130400°S 2A 169.5936438°E 45.6112361°S 3A 169.5946588°E 45.6072369°S 1B 169.5742960°E 45.6280976°S 2B 169.5736889°E 45.6298715°S 3B 169.5782216°E 45.6246010°S 1C 169.5804327°E 45.6449668°S 2C 169.5799403°E 45.6467284°S 3C 169.5823808°E 45.6461454°S – Cheyenne Oct 05 '22 at 21:51
  • You coordinates are OK, just make sure they are separated and `sf::st_as_st()` function will be able to convert it to points. – Grzegorz Sapijaszko Oct 06 '22 at 08:45