Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Find the length of a road in R

Question

I have a dataframe df which contains cartesian coordinates of a hypothetical road. I want to find the length of the road. Following is a plot:

library(ggplot2)
ggplot(df) +
  geom_point(aes(x, y2))

enter image description here

My attempt to find the length:

I tried converting df to an sf object and then find length, but it didn’t work as expected:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

library(sf)
df_sf <- st_as_sf(df, coords = c("x", "y2"))

> sf::st_length(df_sf)
  [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 [36] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 [71] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[106] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Is there a way I can convert the df to a polyline sf object and then find the length? Any other suggestions?

Data

df <- structure(list(x = c(12158, 12158, 12158, 12158, 12158, 12158, 
12158, 12158, 12158, 12158, 12157.999023, 12158, 12158, 12156.886719, 
12154.849609, 12151.196289, 12147.6875, 12143.267578, 12137.9375, 
12131.700195, 12124.556641, 12116.507813, 12107.557617, 12097.708984, 
12086.962891, 12075.326172, 12062.798828, 12049.386719, 12035.092773, 
12019.921875, 12003.879883, 11986.969727, 11969.197266, 11950.568359, 
11931.087891, 11910.761719, 11889.597656, 11867.599609, 11844.777344, 
11821.134766, 11796.681641, 11771.423828, 11745.369141, 11718.525391, 
11690.901367, 11662.505859, 11633.345703, 11603.432617, 11572.773438, 
11541.37793, 11509.255859, 11476.417969, 11442.87207, 11408.630859, 
11373.703125, 11338.099609, 11301.831055, 11264.910156, 11227.345703, 
11189.151367, 11150.337891, 11110.916016, 11070.899414, 11030.299805, 
10989.128906, 10947.400391, 10905.125, 10862.318359, 10818.991211, 
10794.041016, 10746.004883, 10685.342773, 10493.634766, 10488.304688, 
9822.144531, 9590.665039, 9495.904297, 9393.224609, 9333.71875, 
9274.916016, 9216.833008, 9159.488281, 9102.900391, 9047.083984, 
8992.058594, 8937.839844, 8884.444336, 8831.888672, 8780.1875, 
8729.358398, 8679.416016, 8630.375, 8582.251953, 8535.05957, 
8488.813477, 8443.52832, 8399.21582, 8355.890625, 8313.566406, 
8272.255859, 8231.970703, 8192.724609, 8154.52832, 8117.394043, 
8081.33252, 8046.355469, 8012.473633, 7979.696289, 7948.03418, 
7917.49707, 7888.09375, 7859.833984, 7832.725586, 7806.776855, 
7781.996094, 7758.390625, 7735.967773, 7714.734375, 7694.696777, 
7675.861328, 7658.23291, 7641.818359, 7626.621094, 7612.646973, 
7599.899414, 7588.383301, 7578.101074, 7569.056152, 7561.251953, 
7554.689941, 7548.160156, 7544.127441, 7540.84082, 7538, 7538, 
7538), y2 = c(15255, 14520, 13200, 11880, 10560, 9240, 7920, 
6600, 5280, 3960, 2786.666992, 2640, 1916.935059, 1725.494141, 
1646.221191, 1567.054199, 1514.8125, 1462.640137, 1410.552734, 
1358.566406, 1306.697266, 1254.959961, 1203.371582, 1151.947266, 
1100.702148, 1049.652832, 998.813965, 948.202148, 897.831543, 
847.718262, 797.877441, 748.32373, 699.073242, 650.140137, 601.539551, 
553.286621, 505.395508, 457.881348, 410.758301, 364.040527, 317.742676, 
271.878418, 226.462402, 181.507324, 137.02832, 93.037598, 49.549316, 
6.57666, -35.867188, -77.769531, -119.118164, -159.899414, -200.101074, 
-239.711914, -278.71875, -317.109863, -354.874023, -391.999023, 
-428.474609, -464.288574, -499.430664, -533.890137, -567.65625, 
-600.719238, -633.067871, -664.693848, -695.585938, -725.736328, 
-755.134277, -771.569336, -802.256348, -839.523926, -951.065918, 
-954.111816, -1334.774658, -1468.841064, -1526.266846, -1591.573242, 
-1631.31665, -1672.092529, -1713.888184, -1756.691406, -1800.489014, 
-1845.267334, -1891.012939, -1937.712158, -1985.350342, -2033.913086, 
-2083.385742, -2133.753174, -2185, -2237.110596, -2290.069336, 
-2343.859619, -2398.465576, -2453.870117, -2510.056641, -2567.007813, 
-2624.706787, -2683.135254, -2742.276123, -2802.11084, -2862.621338, 
-2923.789307, -2985.596191, -3048.022949, -3111.050537, -3174.659912, 
-3238.831543, -3303.546143, -3368.783691, -3434.524414, -3500.748535, 
-3567.435547, -3634.56543, -3702.117188, -3770.071045, -3838.405762, 
-3907.100586, -3976.134766, -4045.486816, -4115.13623, -4185.061523, 
-4255.241211, -4325.654297, -4396.279297, -4467.094238, -4538.078125, 
-4609.208496, -4680.464844, -4770.95166, -4848.422363, -4943.858398, 
-5270.765625, -5280, -7920)), row.names = c(NA, -136L), class = "data.frame")

>Solution :

To do this in sf, you can convert into a linestring and use st_length

sf::st_length(sf::st_linestring(as.matrix(df)))
#> [1] 25077.29

Note though that you don’t need sf at all here, as you get the same result using a basic Euclidean distance calculation:

sum(sqrt(diff(df$x)^2 + diff(df$y2)^2))
#> [1] 25077.29
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading