I am looking to get not the length of the overall multilinestring but rather the length of the component parts. Here is what I have so far:


s1 <- rbind(c(0,3),c(0,4),c(1,5),c(2,5))
s2 <- rbind(c(0.2,3), c(0.2,4), c(1,4.8), c(2,4.8))
s3 <- rbind(c(0,4.4), c(0.6,5))
mls <- st_multilinestring(list(s1,s2,s3))

# calculate overall length

# split multilinestring into component linestring objects
mls_points <- st_cast(mls, "MULTIPOINT")
mls_split <- st_split(mls, mls_points)

plot(mls_points, add = TRUE, col = "red")

# error on length of split output

Error: inherits(x, "sfc_LINESTRING") || inherits(x, "sfc_MULTILINESTRING") is not TRUE

enter image description here

Maybe there is something I am supposed to be doing with st_cast?

2 Answers 2


Create an sfc first, then use st_cast, which will split it into LINESTRINGs:

> st_length(st_cast(st_sfc(mls),"LINESTRING"))
[1] 3.4142136 3.1313708 0.8485281

these sum to st_length(mls).

Took some digging to figure this out, the help wasn't helpful:

the ‘st_cast’ method for ‘sf’ objects can only split geometries, e.g. cast ‘MULTIPOINT’ into multiple ‘POINT’ features.

until I realised it said "for sf objects" and you didn't have a sf object, you had an sfg object. Not sure why st_cast doesn't split those but the solution is fairly simple once you know!


This probably isn't very elegant, but

# split multilinestring into component linestring objects and then to points
mls_pts <- st_sfc(mls) %>%
  st_cast(., 'LINESTRING') %>%
  lapply(., function(x) {
    st_sfc(x) %>% 
      st_cast(., 'POINT')})

# get distances between points
mls_seglengths <- lapply(mls_pts, function(d) {
  start <- 1:(length(d)-1)
  end   <- 2:length(d)
  dists <- mapply(function(a,b) {st_distance(d[a], d[b])}, a = start, b = end)
  • Nice work! I think I misled you a bit with the figure. @Spacedman had the solution I was after.
    – jsta
    Oct 4, 2017 at 12:53
  • hah yeah I was bored at work and overshot the mark :P. That sf/sfc/sfg divide really needs more clarification too...
    – obrl_soil
    Oct 4, 2017 at 13:31

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.