[R-sig-Geo] df with embedded wkt lists to sf

Howard, Tim G (DEC) t|m@how@rd @end|ng |rom dec@ny@gov
Fri Jun 10 13:16:17 CEST 2022


Josiah, 
Interesting, thanks for working out and posting this approach. It may be just as complex and convoluted as what I've come up with! Dis-associating the line strings to points and then re-aggregating them to lines using group-by seems iffy to me, but it works (and for polygons as well). 

Of course I've got a much larger attribute table than just a "comments" column so the spot where you define 'coords=c(2,3)' doesn't work. But I've come up with a work-around to that by finding the location of the lon/lat columns before starting. And the attribute table is lost so it needs to be joined back in a step not needed in my approach. 

I guess this confirms that there isn't already a part of  st_as_sf​ I was missing!
Thanks again, 
Tim


From: Josiah Parry <josiah.parry using gmail.com>
Sent: Thursday, June 9, 2022 4:39 PM
To: Howard, Tim G (DEC) <tim.howard using dec.ny.gov>
Cc: r-sig-geo using r-project.org <r-sig-geo using r-project.org>
Subject: Re: [R-sig-Geo] df with embedded wkt lists to sf 
 
ATTENTION: This email came from an external source. Do not open attachments or click on links from unknown senders or unexpected emails.

Furthermore, if you want to get these points into a linstring you can combine the points by group (comment) and then cast them to a line like so below.  

This is an interesting use case! Thanks for introducing me to it. 

dat_sf |> 
  dplyr::group_by(comment) |> 
  dplyr::summarise(geometry = sf::st_cast(
    sf::st_combine(geometry), "LINESTRING"
    )) 

On Thu, Jun 9, 2022 at 4:34 PM Josiah Parry <josiah.parry using gmail.com> wrote:
Hey Tim, 

The key thing here is to separate the long / lat points into elements in a vector. You can do this with a string split. Afterwards, separate these into their own rows like I've done below. 

I think this should get you on the right path! 


dat <- dget(textConnection(txtString))

dat |> 
  tidyr::unnest(c(longitude, latitude)) |> 
  dplyr::mutate(longitude = strsplit(longitude, "; "),
                latitude = strsplit(latitude, "; ")) |> 
  tidyr::unnest(c(longitude, latitude)) |> 
  sf::st_as_sf(coords = c(2, 3), crs = 4326)

On Thu, Jun 9, 2022 at 3:48 PM Howard, Tim G (DEC) via R-sig-Geo <r-sig-geo using r-project.org> wrote:
Howdy all - 
There's probably a way to do this much​ more simply than I've figured it out, so it's a bit embarrassing but here goes. I'm getting data out of a shiny app that looks like the following, with lists of coordinates within separate longitude and latitude columns. 

Is there more efficient way to get an `sf` collection than what I've got? Perhaps an `apply` replacement for the for() loop? Using a tibble because that's how `googlesheets4` gives it to me. 

# set up a couple of lines strings. lists within data.frame/tibble
txtString <- 'structure(list(comment = c("line one", "line two"), 
longitude = list("-115.138577; -114.942454; -114.170219", "-118.411382; -118.153971; -117.83527; -117.246901; -117.026262; -117.185613"), 
latitude = list("37.527588; 38.234088; 38.368805", "41.296472; 41.645606; 41.819467; 41.837741; 41.590604; 41.333312")), 
row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"))'

dat <- dget(textConnection(txtString))

# function for parsing the text strings
getWKT <- function(x){
  st_linestring(matrix(
    c(as.numeric(unlist(strsplit(x$longitude[[1]],";"))),
      as.numeric(unlist(strsplit(x$latitude[[1]],";")))),
    byrow = FALSE, ncol = 2)
  )
}

# populate dataframe/tibble by going back to sf text
dat$wkt <- NA
for(i in 1:nrow(dat)){
  dat$wkt[[i]] <- st_as_text(getWKT(dat[i,]))
}

# finally make the sf collection
dat_sf <- st_as_sf(dat, wkt = "wkt", crs = 4326)


Thanks in advance for any tips. 
Tim
_______________________________________________
R-sig-Geo mailing list
R-sig-Geo using r-project.org
https://stat.ethz.ch/mailman/listinfo/r-sig-geo


More information about the R-sig-Geo mailing list