R: sf package points to multiple lines with st_cast

I want to create multiple lines out of given points as sf objects.

If I have a number of points as

library(sf)
pts <- st_multipoint(matrix(c(10, 10, 15, 20, 30, 30), nrow = 3, byrow = TRUE), dim = "XY")

and I am using st_cast to create lines of them

lines <- st_cast(pts, "MULTILINESTRING")

I will always get one sf object with multiple segments, but what I want to get is multiple lines (two in this example).

• What result would you like to get? With three points A, B, and C you can make 3 different lines: AB, AC, BC. What if your matrix has a hundred lines? Feb 8 '18 at 8:28
• It sounds like you want the sf equivalent of this postgis procedure - gis.stackexchange.com/questions/174472/…, which AFAIK is not possible...yet. Maybe raise an issue on sf's github page? Feb 8 '18 at 12:25

I think that the sf package need to know first how you want to create the lines from your points. I mean which pair of POINT make every LINESTRING. In my example that was defined inside the lapply function. Follow the reproducible and commented code below, hope that helps:

library(sf)

# Create points data
multipoints <- st_multipoint(matrix(c(10, 10, 15, 20, 30, 30), nrow = 3, byrow = TRUE), dim = "XY")
points <- st_cast(st_geometry(multipoints), "POINT")

# Number of total linestrings to be created
n <- length(points) - 1

# Build linestrings
linestrings <- lapply(X = 1:n, FUN = function(x) {

pair <- st_combine(c(points[x], points[x + 1]))
line <- st_cast(pair, "LINESTRING")
return(line)

})

# One MULTILINESTRING object with all the LINESTRINGS
multilinetring <- st_multilinestring(do.call("rbind", linestrings))

# Plot
plot(multipoints, pch = 19, cex = 2)
plot(multilinetring[], col = "orange", lwd = 2, add = TRUE)
plot(multilinetring[], col = "green", lwd = 2, add = TRUE) • Thank you Guzmán for your answer! This solution works if the order of the given points is the same as the order of the lines to be created. But if there is another ordering in the sf object (like matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)) it creates a line which link the lower left with the upper right point in this case. user30184 mentioned this in his comment above. Is there a possibility to sort the points per minimal distance or something like that? Thanks! Feb 9 '18 at 11:02

I have found a solution! For all of the others, which are looking for an answer as well, the way I have solved it:

library(sf)

# create points data
m <- matrix(c(10, 10, 30, 30, 15, 20), nrow = 3, byrow = TRUE)
multipoints <- st_multipoint(m, dim = "XY")

# save ranges of coordinates
x.range <- max(m[,1]) - min(m[,1])
y.range <- max(m[,2]) - min(m[,2])

# order by greatest range
if (x.range > y.range) {
sort.id <- order(m[,1])
} else if (y.range > x.range) {
sort.id <- order(m[,2])
} else if (y.range == x.range) {
sort.id <- order(m[,2])
}

# creat lines by previous sorting and save them in the list
lines <- lapply(1:(length(sort.id)-1), function(i) {
st_linestring(rbind(multipoints[sort.id[i],], multipoints[sort.id[i+1],]))
})

# plot results
plot(multipoints)
plot(lines[], col = "orange", lwd = 2, add = TRUE)
plot(lines[], col = "green", lwd = 2, add = TRUE) Nevertheless, thanks again for your help!