rdataframegiseuclidean-distancespatial-data

How to Calculate Euclidean distance from sf data frame points in R


How do I calculate Euclidean distance in km from a spatial point that has been converted from a geometry column into a data frame. (The points are points which were derived from a spatial join of spatial data and polygon centroids)

I tried data_sample <- data_sample %>% mutate(distance= distm(cbind(origin_y,origin_x), cbind(dest_y,dest_x),fun = distHaversine)/1000)

and the error i'm getting is Error in .pointsToMatrix(x) : longitude > 360

Below is a sample data frame
data_sample <- data.frame(
    origin_x = c(
        623613.87,
        625678.02,
        625678.02,
        624359.91,
        628136.40,
        628136.40,
        628136.40,
        628136.40,
        632329.70
    ),
    origin_y = c(
        6438093.66,
        6455468.02,
        6455468.02,
        6449819.06,
        6462017.42,
        6462017.42,
        6462017.42,
        6462017.42,
        6446947.75
    ),
    dest_x = c(
        659627.84,
        642136.20,
        642136.20,
        630395.03,
        628422.74,
        642136.20,
        642136.20,
        659627.84,
        659627.84
    ),
    dest_y = c(
        6473200.36,
        6456562.78,
        6456562.78,
        6451979.98,
        6459817.02,
        6456562.78,
        6456562.78,
        6473200.36,
        6473200.36)
)


Solution

  • Is there any reason not to use the sf builtin function st_distance??

    library(sf)
    # Using your data, but separate data.frames
    origin_df <- data.frame(
        origin_x = c(623613.87,
                625678.02,
                625678.02,
                624359.91,
                628136.40,
                628136.40,
                628136.40,
                628136.40,
                632329.70
            ),         
        origin_y = c(
                6438093.66,
                6455468.02,
                6455468.02,
                6449819.06,
                6462017.42,
                6462017.42,
                6462017.42,
                6462017.42,
                6446947.75)
        )
        
    dest_df <- data.frame(
        dest_x = c(
                659627.84,
                642136.20,
                642136.20,
                630395.03,
                628422.74,
                642136.20,
                642136.20,
                659627.84,
                659627.84
            ),
        dest_y = c(
                6473200.36,
                6456562.78,
                6456562.78,
                6451979.98,
                6459817.02,
                6456562.78,
                6456562.78,
                6473200.36,
                6473200.36)
        )
    # Now convert to sf objects
    # Just guessing at the CRS. Replace with the correct one
    origin_sf = st_as_sf(origin_df, coords=c("origin_x", "origin_y"), crs="EPSG:32632")  
    dest_sf <- st_as_sf(dest_df, coords=c("dest_x", "dest_y"), crs="EPSG:32632")
    
    # Now get the distance matrix, (will be in meters, since the CRS units are meters
    dist_matrix <- st_distance(origin_sf, dest_sf)
    # Dispaly in kilometers
    (dist_matrix)
             [,1]     [,2]     [,3]      [,4]      [,5]     [,6]     [,7]     [,8]
     [1,] 50.29400 26.15693 26.15693 15.453608 22.249261 26.15693 26.15693 50.29400
     [2,] 38.30178 16.49455 16.49455  5.866567  5.142693 16.49455 16.49455 38.30178
     [3,] 38.30178 16.49455 16.49455  5.866567  5.142693 16.49455 16.49455 38.30178
     [4,] 42.31444 19.01248 19.01248  6.410324 10.791932 19.01248 19.01248 42.31444
     [5,] 33.41809 15.02490 15.02490 10.288421  2.218953 15.02490 15.02490 33.41809
     [6,] 33.41809 15.02490 15.02490 10.288421  2.218953 15.02490 15.02490 33.41809
     [7,] 33.41809 15.02490 15.02490 10.288421  2.218953 15.02490 15.02490 33.41809
     [8,] 33.41809 15.02490 15.02490 10.288421  2.218953 15.02490 15.02490 33.41809
     [9,] 37.87331 13.73376 13.73376  5.391316 13.449255 13.73376 13.73376 37.87331
              [,9]
     [1,] 50.29400
     [2,] 38.30178
     [3,] 38.30178
     [4,] 42.31444
     [5,] 33.41809
     [6,] 33.41809
     [7,] 33.41809
     [8,] 33.41809
     [9,] 37.87331
    

    And responding to the additional comment from william-g-k:

    dist_km = dist_matrix / 1000
    dist_km = as.data.frame(matrix(dist_km, nrow=1))