Purrr flatten_dfr

266 views Asked by At

I'm trying to extract a list of lists that hold coordinate information into a sf dataframe.

Here is the list

feature <- list(type = "Feature", properties = list(`_leaflet_id` = 26065L, 
feature_type = "polyline"), geometry = list(type = "LineString", 
coordinates = list(list(-74.210091, 40.382121), list(-73.942375, 
    40.661889))))

and I would like to convert it to a sf dataframe of 3 columns (leaflet_id, feature_type, geometry)

I've tried using purrr::flatten_dfr(feature) but get the error: argument 1 must have names.

I've reviewed other SO posts like below which seem promising but wasn't working.

Thanks

Error in bind_rows_(x, .id) : Argument 1 must have names

2

There are 2 answers

0
SymbolixAU On BEST ANSWER

Your feature list looks like the result of reading geojson using something like jsonlite::fromJSON().

If you read the geojson directly using sf::st_read() you'll get your sf object.

To fix your code as-is, you can do

library(jsonlite)
library(sf)

sf <- jsonlite::toJSON( feature, auto_unbox = TRUE ) %>%
    sf::st_read()

sf
# Simple feature collection with 1 feature and 2 fields
# geometry type:  LINESTRING
# dimension:      XY
# bbox:           xmin: -74.21009 ymin: 40.38212 xmax: -73.94238 ymax: 40.66189
# z_range:        zmin: NA zmax: NA
# m_range:        mmin: NA mmax: NA
# geographic CRS: WGS 84
# _leaflet_id feature_type                       geometry
# 1       26065     polyline LINESTRING (-74.21009 40.38...
0
andrew_reece On

There are two issues with your list that will throw errors with flatten_dfr.

  1. Not all of your nested lists are named. The two lists in coordinates need names.
  2. You use the list name type twice. This won't work, because your data frame after flatten will have two columns with the same name.

If you fix those issues, flatten_dfr will run without error:

feature <- list(type = "Feature", 
                properties = list(`_leaflet_id` = 26065L, 
                                  feature_type = "polyline"), 
                geometry = list(type1 = "LineString", 
                                coordinates = list(foo=list(-74.210091, 40.382121), 
                                                   bar=list(-73.942375, 
 
flatten_dfr(feature)
# A tibble: 2 x 5
  type    `_leaflet_id` feature_type type1      coordinates 
  <chr>           <int> <chr>        <chr>      <named list>
1 Feature         26065 polyline     LineString <list [2]>  
2 Feature         26065 polyline     LineString <list [2]>