# 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? Commented Feb 8, 2018 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? Commented Feb 8, 2018 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:

``````# Load library
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[[1]], col = "orange", lwd = 2, add = TRUE)
plot(multilinetring[[2]], 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! Commented Feb 9, 2018 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:

``````# Load library
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[[1]], col = "orange", lwd = 2, add = TRUE)
plot(lines[[2]], col = "green", lwd = 2, add = TRUE)
``````

Nevertheless, thanks again for your help!