0

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)
)

2 Answers 2

0

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))
Sign up to request clarification or add additional context in comments.

1 Comment

thanks works perfectly, but how do I add the distances as a column to a data frame?
0

I am not 100% sure but looks like a problem with the coordinate system. I guess the distm()function takes values in degrees for latitude and longitude. Before converting the geometry column to data frame change the coordinate system of your data. From package 'sf' use st_crs() to find the current coordinate system and change to something like WGS 84 using st_transform().

4 Comments

So it happens that st_as_sf cannot take 4 columns with longitude and latitude (origin_x, origin_y & dest_x,dest_y) at the same time so its quite difficult to convert the geographic columns to geometry.
How about breaking into two dataframe and you can still use distm(), I guess.
@Micha method works like how I want it but I need to convert it into a single column and add to a data frame. Any ideas?
I don't understand what you are trying to do, but isn't that simple matrix manipulation? see my edits to the answer...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.