R – Creating sf Lines from data.frame with Long Lat Coordinates

linestringrsf

I want to create an sf object from a data.frame that contains multiple coordinates under different columns for each row. In the data below, each ID contains start and end coordinates for both latitude and longitude.

enter image description here

structure(list(ID = c("1001A", "1002A", "1003A", "1004A", "1005A", 
"1006A", "1007A", "1008A", "1009A", "1010A"), StartLat = c(33.53418, 
33.60399, 33.40693, 33.64672, 33.57127, 33.42848, 33.54936, 33.49554, 
33.5056, 33.61696), StartLong = c(-112.09114, -111.92731, -112.02982, 
-111.92548, -112.04899, -112.0998, -112.09123, -111.9687, -112.05629, 
-111.98657), EndLat = c(33.53488, 33.60401, 33.40687, 33.64776, 
33.57125, 33.42853, 33.54893, 33.49647, 33.5056, 33.61654), EndLong = c(-112.09114, 
-111.93097, -112.03429, -111.93031, -112.04807, -112.09929, -112.09122, 
-111.97105, -112.0541, -111.98657)), row.names = c(3028L, 8618L, 
6322L, 1171L, 691L, 6590L, 2008L, 4552L, 2894L, 1909L), class = "data.frame")

I tried using the sf package's st_as_sf function, but it yields an error:

dfr_sf <- st_as_sf(dfr, coords = c(c("StartLong", "EndLong"), c("StartLat", "EndLat")), crs = "+proj=longlat +datum=WGS84")
#> Error in points_rcpp(as.matrix(cc), dim) : 
#>  dim(pts)[2] == nchar(gdim) is not TRUE

The start and end coordinates in each row define a road segment. All the coordinates should go under the geometry column in the final sf object so that these can be plotted as polylines.

Best Answer

I'm solving your problem by looping through lines in the data.frame and by building the LINESTRING matrix of each pair of coordinates

library(sf)
ls <- apply(dfr, 1, function(x) 
{
  v <- as.numeric(x[c(3,5,2,4)])
  m <- matrix(v, nrow = 2)
  return(st_sfc(st_linestring(m), crs = 4326))
})
ls = Reduce(c, ls)
ls$ID = dfr$ID